diff --git a/.gitignore b/.gitignore
index 326bcde..c2fb61f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,5 +4,9 @@ node_modules
.idea/
+upload
+docker-compose.yml
.env
+
+coverage/
\ No newline at end of file
diff --git a/lib/7dc6da2fbc3e960f6bf7aa15fa68a16b.png b/lib/7dc6da2fbc3e960f6bf7aa15fa68a16b.png
new file mode 100644
index 0000000..09af143
Binary files /dev/null and b/lib/7dc6da2fbc3e960f6bf7aa15fa68a16b.png differ
diff --git a/lib/application/use_cases/artist/getArtist.js b/lib/application/use_cases/artist/getArtist.js
new file mode 100644
index 0000000..31eba13
--- /dev/null
+++ b/lib/application/use_cases/artist/getArtist.js
@@ -0,0 +1,145 @@
+const serializeArtiste = require("../../../interfaces/serializers/ArtistSerializer");
+const throwStatusCode = require("../utils/throwStatusCode");
+const UserPublic = require("../../../domain/model/UserPublic");
+const ArtistPage = require("../../../domain/model/ArtistPage.js");
+const serializeAlbum = require("../../../interfaces/serializers/AlbumSerializer");
+const reviewSerializer = require("../../../interfaces/serializers/ReviewSerializer.js");
+module.exports = async (
+ artistId,
+ userToken,
+ {
+ accessTokenManager,
+ userRepository,
+ spotifyRepository,
+ reviewRepository,
+ followRepository,
+ friendRepository,
+ }
+) => {
+ const id_utilisateur = accessTokenManager.decode(userToken)?.value;
+ const user = await userRepository.getByUser(id_utilisateur);
+ if (!user)
+ throwStatusCode(401, "votre token d'authentification n'est pas le bon");
+ const artist = await spotifyRepository.getSpotifyArtist(artistId);
+ if (artist.error) throwStatusCode(artist.error.status, artist.error.message);
+ const doesUserFollow = await followRepository.doesFollows(
+ id_utilisateur,
+ artistId
+ );
+ const albums = await spotifyRepository.getSpotifyArtistSongs(
+ artistId,
+ "album,single"
+ );
+
+ const album_ids = albums.items.map((album) => album.id);
+ const [
+ follower_count,
+ friends_followers,
+ friend_follower_count,
+ reviewsByLike,
+ reviewsByTime,
+ reviewsByFriends,
+ ] = await Promise.all([
+ followRepository.getFollowersCount(artistId),
+ followRepository.getFriendsFollowing(artistId, user.id_utilisateur, 3),
+ followRepository.getFriendsFollowingCount(artistId, user.id_utilisateur),
+ reviewRepository.getOeuvreReviews(
+ 1,
+ 3,
+ true,
+ false,
+ false,
+ album_ids,
+ user.id_utilisateur
+ ),
+ reviewRepository.getOeuvreReviews(
+ 1,
+ 3,
+ false,
+ false,
+ false,
+ album_ids,
+ user.id_utilisateur
+ ),
+ reviewRepository.getOeuvreReviews(
+ 1,
+ 3,
+ false,
+ false,
+ true,
+ album_ids,
+ user.id_utilisateur
+ ),
+ ]);
+ return await artistSerizilizer(
+ user.id_utilisateur,
+ doesUserFollow,
+ artist,
+ albums,
+ follower_count,
+ friends_followers,
+ friend_follower_count,
+ reviewsByLike,
+ reviewsByTime,
+ reviewsByFriends,
+ { reviewRepository, spotifyRepository, friendRepository }
+ );
+};
+
+const artistSerizilizer = async (
+ id_utilisateur,
+ doesUserFollow,
+ artist,
+ albums,
+ followers_count,
+ friends_followers,
+ friend_follower_count,
+ reviewsByLike,
+ reviewsByTime,
+ reviewsByFriends,
+ { reviewRepository, spotifyRepository, friendRepository }
+) => {
+ artist.follower_count = followers_count;
+ artist = serializeArtiste(artist);
+
+ albums = await Promise.all(
+ albums.items.map(async (item) => {
+ item.rating = await reviewRepository.getOeuvreRating(item.id);
+ item.reviewCount = await reviewRepository.getReviewCount(item.id);
+ return serializeAlbum(item);
+ })
+ );
+
+ friends_followers = {
+ count: friend_follower_count,
+ users: friends_followers.map((item) => {
+ return new UserPublic(item);
+ }),
+ };
+ const serializeReviews = (reviews) => {
+ return reviews.map(async (review) => {
+ return reviewSerializer(
+ review,
+ id_utilisateur,
+ undefined,
+ spotifyRepository,
+ reviewRepository,
+ friendRepository
+ );
+ });
+ };
+ reviewsByLike = await Promise.all(serializeReviews(reviewsByLike));
+
+ reviewsByTime = await Promise.all(serializeReviews(reviewsByTime));
+
+ reviewsByFriends = await Promise.all(serializeReviews(reviewsByFriends));
+ return new ArtistPage(
+ artist,
+ albums,
+ friends_followers,
+ reviewsByLike,
+ reviewsByTime,
+ reviewsByFriends,
+ doesUserFollow
+ );
+};
diff --git a/lib/application/use_cases/artist/getArtistFollowers.js b/lib/application/use_cases/artist/getArtistFollowers.js
new file mode 100644
index 0000000..a38380a
--- /dev/null
+++ b/lib/application/use_cases/artist/getArtistFollowers.js
@@ -0,0 +1,41 @@
+const throwStatusCode = require("../utils/throwStatusCode.js");
+const ArtistFollowersPage = require("../../../domain/model/ArtistFollowersPage.js");
+const UserPublic = require("../../../domain/model/UserPublic.js");
+
+module.exports = async (artistId, userToken, {accessTokenManager,userRepository, spotifyRepository, followRepository, friendRepository}) => {
+ const id_utilisateur = accessTokenManager.decode(userToken)?.value
+ const user = await userRepository.getByUser(id_utilisateur)
+ if(!user) throwStatusCode(401,"votre token d'authentification n'est pas le bon")
+
+ const artist = await spotifyRepository.getSpotifyArtist(artistId)
+ if(artist.error)
+ throwStatusCode(artist.error.status,artist.error.message)
+
+ const followersFriendsList = await followRepository.getFriendsFollowing(artistId,id_utilisateur)
+ const followersWithoutFriends = await followRepository.getArtistFollowersWithoutFriends(artistId, id_utilisateur)
+
+ const followersFriendsList2 = await Promise.all(followersFriendsList.map(async (item) => {
+ const areFriends = await friendRepository.areFriends(id_utilisateur, item.id_utilisateur);
+ const userPublicFriends = new UserPublic(item)
+ return {
+ ...userPublicFriends,
+ areFriends: areFriends
+ };
+ }));
+
+ const followersWithoutFriendst2 = await Promise.all(followersWithoutFriends.map(async (item) => {
+ let areFriends = await friendRepository.areFriends(id_utilisateur, item.id_utilisateur);
+ const userPublicNoFriends = new UserPublic(item)
+ if(id_utilisateur == item.id_utilisateur) {
+ areFriends = false
+ }
+ return {
+ ...userPublicNoFriends,
+ areFriends: areFriends
+ };
+ }));
+
+ const allFollowers = [...followersFriendsList2, ...followersWithoutFriendst2];
+
+ return new ArtistFollowersPage(artist, allFollowers)
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/comment/deleteComment.js b/lib/application/use_cases/comment/deleteComment.js
new file mode 100644
index 0000000..5696644
--- /dev/null
+++ b/lib/application/use_cases/comment/deleteComment.js
@@ -0,0 +1,14 @@
+const throwStatusCode = require("../utils/throwStatusCode");
+module.exports = async (
+ idComment,
+ userToken,
+ { accessTokenManager, userRepository, commentRepository }
+) => {
+ const id_utilisateur = accessTokenManager.decode(userToken)?.value;
+ if (!(await userRepository.getByUser(id_utilisateur)))
+ throwStatusCode(401, "votre token d'authentification n'est pas le bon");
+ if (!(await commentRepository.canDelete(idComment, id_utilisateur)))
+ throwStatusCode(403, "ce n'est pas votre post");
+
+ await commentRepository.delete(idComment, id_utilisateur);
+};
diff --git a/lib/application/use_cases/comment/getComment.js b/lib/application/use_cases/comment/getComment.js
new file mode 100644
index 0000000..3080458
--- /dev/null
+++ b/lib/application/use_cases/comment/getComment.js
@@ -0,0 +1,142 @@
+const reviewSerializer = require("../../../interfaces/serializers/ReviewSerializer");
+const PublicComment = require("../../../domain/model/PublicComment");
+const UserPublic = require("../../../domain/model/UserPublic");
+const throwStatusCode = require("../utils/throwStatusCode");
+
+
+module.exports = async (
+ id_com,
+ page,
+ pageSize,
+ orderByLike,
+ userToken,
+ {
+ reviewRepository,
+ commentRepository,
+ accessTokenManager,
+ userRepository,
+ friendRepository,
+ spotifyRepository,
+ }
+) => {
+ const id_utilisateur = accessTokenManager.decode(userToken)?.value;
+ if (!(await userRepository.getByUser(id_utilisateur)))
+ throwStatusCode(401, "votre token d'authentification n'est pas le bon");
+ const mainComment = await commentRepository.getById(id_com);
+ if (!mainComment) throwStatusCode(404, "commentaire introuvable");
+ const commentsRaw = await commentRepository.getCommentsComments(
+ id_com,
+ id_utilisateur,
+ true,
+ page,
+ pageSize,
+ orderByLike
+ );
+ const review = await reviewRepository.getById(mainComment.id_review);
+ let previousComments = [];
+ let nextCommentsId = mainComment.id_reponse;
+ while (nextCommentsId) {
+ previousComments.push(await commentRepository.getById(nextCommentsId));
+ nextCommentsId = previousComments.at(-1).id_reponse;
+ }
+ return await serialize(
+ id_utilisateur,
+ mainComment,
+ previousComments,
+ commentsRaw,
+ review,
+ { spotifyRepository, friendRepository, commentRepository, reviewRepository }
+ );
+};
+
+const serialize = async (
+ id_utilisateur,
+ comment,
+ previousComments,
+ comments,
+ review,
+ { spotifyRepository, friendRepository, commentRepository, reviewRepository }
+) => {
+ const serializeReview = async () => {
+ return !review.utilisateur.is_private ||
+ friendRepository.areFriends(
+ id_utilisateur,
+ review.utilisateur.id_utilisateur
+ )
+ ? reviewSerializer(
+ review,
+ id_utilisateur,
+ comments,
+ spotifyRepository,
+ reviewRepository,
+ friendRepository
+ )
+ : {
+ private: true,
+ };
+ };
+ const serializeComment = async () => {
+ const doesUserLike = await commentRepository.doesUserLike(
+ id_utilisateur,
+ comment.id_com
+ );
+ comment.doesUserLike = doesUserLike;
+ return !comment.utilisateur.is_private ||
+ friendRepository.areFriends(
+ id_utilisateur,
+ comment.utilisateur.id_utilisateur
+ )
+ ? new PublicComment(comment, new UserPublic(comment.utilisateur))
+ : {
+ private: true,
+ };
+ };
+ const serializedPreviousComments = Promise.all(
+ previousComments.map(async (comment) => {
+ const doesUserLike = await commentRepository.doesUserLike(
+ id_utilisateur,
+ comment.id_com
+ );
+ comment.doesUserLike = doesUserLike;
+ return !comment.utilisateur.is_private ||
+ friendRepository.areFriends(
+ id_utilisateur,
+ comment.utilisateur.id_utilisateur
+ )
+ ? new PublicComment(comment)
+ : {
+ private: true,
+ };
+ })
+ );
+ const serializedComments = Promise.all(
+ comments.map(async (comment) => {
+ const doesUserLike = await commentRepository.doesUserLike(
+ id_utilisateur,
+ comment.id_com
+ );
+ comment.doesUserLike = doesUserLike;
+ return !comment.utilisateur.is_private ||
+ friendRepository.areFriends(
+ id_utilisateur,
+ comment.utilisateur.id_utilisateur
+ )
+ ? new PublicComment(comment, new UserPublic(comment.utilisateur))
+ : {
+ private: true,
+ };
+ })
+ );
+ const promise = await Promise.all([
+ serializeReview(),
+ serializeComment(),
+ serializedPreviousComments,
+ serializedComments,
+ ]);
+ return {
+ review: promise[0],
+ comment: promise[1],
+ previousComments: promise[2],
+ comments: promise[3],
+ };
+};
diff --git a/lib/application/use_cases/comment/likeComment.js b/lib/application/use_cases/comment/likeComment.js
new file mode 100644
index 0000000..188bc7f
--- /dev/null
+++ b/lib/application/use_cases/comment/likeComment.js
@@ -0,0 +1,11 @@
+const throwStatusCode = require("../utils/throwStatusCode");
+module.exports = async (commentId,userToken,{accessTokenManager,userRepository,commentRepository}) =>{
+ const id_utilisateur = accessTokenManager.decode(userToken)?.value
+ if(! await commentRepository.getById(commentId)) throwStatusCode(404,"commentaire introuvable")
+ if(! await userRepository.getByUser(id_utilisateur)) throwStatusCode(401,"votre token d'authentification n'est pas le bon")
+ if(! await commentRepository.doesUserLike(commentId,id_utilisateur)){
+ await commentRepository.like(commentId,id_utilisateur,)
+ return true
+ }
+ await commentRepository.unlike(commentId,id_utilisateur)
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/comment/putComment.js b/lib/application/use_cases/comment/putComment.js
new file mode 100644
index 0000000..838d54b
--- /dev/null
+++ b/lib/application/use_cases/comment/putComment.js
@@ -0,0 +1,16 @@
+const throwStatusCode = require("../utils/throwStatusCode");
+const PublicComment = require("../../../domain/model/PublicComment")
+const UserPublic = require("../../../domain/model/UserPublic")
+module.exports = async (
+ commentId,
+ description,
+ userToken,
+ {friendRepository,accessTokenManager,commentRepository,userRepository}) => {
+ const id_utilisateur = accessTokenManager.decode(userToken)?.value
+ if(! await userRepository.getByUser(id_utilisateur)) throwStatusCode(401,"votre token d'authentification n'est pas le bon")
+ const comment = await commentRepository.getById(commentId)
+ if(comment.utilisateur.is_private && !(await friendRepository.areFriends(id_utilisateur,comment.utilisateur.id_utilisateur)))
+ throwStatusCode(403, "l'utilisateur est en privé")
+ const commentRaw = await commentRepository.persist(comment.id_review,description,id_utilisateur,commentId)
+ return new PublicComment(commentRaw,new UserPublic(comment.utilisateur))
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/friend/acceptRequestUser.js b/lib/application/use_cases/friend/acceptRequestUser.js
new file mode 100644
index 0000000..31ba4e2
--- /dev/null
+++ b/lib/application/use_cases/friend/acceptRequestUser.js
@@ -0,0 +1,23 @@
+'use strict';
+
+const throwStatusCode = require("../utils/throwStatusCode")
+
+module.exports = async (token, amiIdUtilisateur, {accessTokenManager, userRepository, friendRepository}) => {
+ const id = accessTokenManager.decode(token)?.value
+ const user = await userRepository.getByUser(id);
+ if (!user) {
+ throwStatusCode(400,"Votre token d'authentification n'est pas le bon");
+ }
+ const ami = await userRepository.getByUser(amiIdUtilisateur)
+ if(!ami) {
+ throwStatusCode(400,'id ami invalide')
+ }
+
+ const friend = await friendRepository.accept(id, amiIdUtilisateur)
+ if(!friend) {
+ throwStatusCode(403,'Il existe aucune relation entre ces deux utilisateurs')
+ }
+
+ return friend
+}
+
diff --git a/lib/application/use_cases/friend/followUser.js b/lib/application/use_cases/friend/followUser.js
new file mode 100644
index 0000000..bb569ed
--- /dev/null
+++ b/lib/application/use_cases/friend/followUser.js
@@ -0,0 +1,100 @@
+"use strict";
+
+const Friend = require("../../../domain/model/Friend");
+const throwStatusCode = require("../utils/throwStatusCode");
+
+module.exports = async (
+ token,
+ amiIdUtilisateur,
+ { accessTokenManager, friendRepository, userRepository, mailRepository }
+) => {
+ const id = accessTokenManager.decode(token)?.value;
+ const user = await userRepository.getByUser(id);
+ if (!user) {
+ throwStatusCode(400, "Votre token d'authentification n'est pas le bon");
+ }
+ const ami = await userRepository.getByUser(amiIdUtilisateur);
+ if (!ami) {
+ throwStatusCode(400, "id ami invalide");
+ }
+ const followInfo = await friendRepository.getFollowInfo(id, amiIdUtilisateur);
+ console.log(followInfo);
+ if (followInfo.doesFollows) {
+ friendRepository.removeFriendById(id, amiIdUtilisateur);
+ return;
+ }
+ const userRaw = {
+ id_utilisateur: id,
+ amiIdUtilisateur: amiIdUtilisateur,
+ en_attente: ami.is_private,
+ createdAt: undefined,
+ updatedAt: undefined,
+ };
+
+ let friend = new Friend(userRaw);
+ friend = await friendRepository.persist(friend);
+ if (ami.is_private) {
+ const mailOptions = {
+ from: process.env.MAILER_EMAIL,
+ to: ami.email,
+ subject: "Nouvelle demande d'ami sur Solimbo",
+ html: `
+
+
+
+
+
+ Nouvelle demande d'ami sur Solimbo
+
+
+
+
+
+
+
+
Nouvelle demande d'ami sur Solimbo
+
+
Bonjour,
+
Vous avez reçu une nouvelle demande d'ami sur Solimbo de la part de ${user.pseudo}.
+
Connectez-vous à Solimbo pour accepter ou rejeter la demande.
+
+
Accepter la demande
+
+
+
+ `,
+ };
+ await mailRepository.send(mailOptions);
+ }
+ return friend;
+};
diff --git a/lib/application/use_cases/friend/getListFriends.js b/lib/application/use_cases/friend/getListFriends.js
new file mode 100644
index 0000000..6838eef
--- /dev/null
+++ b/lib/application/use_cases/friend/getListFriends.js
@@ -0,0 +1,15 @@
+'use strict';
+
+const throwStatusCode = require("../utils/throwStatusCode")
+
+module.exports = async (token, {accessTokenManager, userRepository, friendRepository}) => {
+ const id = accessTokenManager.decode(token)?.value
+ const user = await userRepository.getByUser(id);
+ if (!user) {
+ throwStatusCode(400,"Votre token d'authentification n'est pas le bon");
+ }
+
+ const friends = await friendRepository.getListFriendsById(id)
+
+ return friends
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/friend/getListFriendsRequest.js b/lib/application/use_cases/friend/getListFriendsRequest.js
new file mode 100644
index 0000000..9f6cd16
--- /dev/null
+++ b/lib/application/use_cases/friend/getListFriendsRequest.js
@@ -0,0 +1,22 @@
+'use strict';
+
+const throwStatusCode = require("../utils/throwStatusCode")
+const UserPublic = require("../../../domain/model/UserPublic.js");
+const ListsFriendsRequestsPage = require("../../../domain/model/ListsFriendsRequestsPage.js");
+
+
+module.exports = async (token, {accessTokenManager, userRepository, friendRepository}) => {
+ const id = accessTokenManager.decode(token)?.value
+ const user = await userRepository.getByUser(id);
+ if (!user) {
+ throwStatusCode(400,"Votre token d'authentification n'est pas le bon");
+ }
+
+ const usersRequestsReceived = await friendRepository.getRequestFriendsById(id)
+ const usersRequestsSend = await friendRepository.getSendRequestFriendsById(id)
+
+ const usersPrivateRequestsReceived = await Promise.all(usersRequestsReceived.map(async (userPublic) => new UserPublic(userPublic)));
+ const usersPrivateRequestsSend = await Promise.all(usersRequestsSend.map(async (userPublic) => new UserPublic(userPublic)));
+
+ return new ListsFriendsRequestsPage(usersPrivateRequestsReceived, usersPrivateRequestsSend)
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/friend/getProfilFriend.js b/lib/application/use_cases/friend/getProfilFriend.js
new file mode 100644
index 0000000..7af357c
--- /dev/null
+++ b/lib/application/use_cases/friend/getProfilFriend.js
@@ -0,0 +1,22 @@
+'use strict';
+
+const throwStatusCode = require("../utils/throwStatusCode")
+
+module.exports = async (token, amiIdUtilisateur, {accessTokenManager, userRepository, friendRepository}) => {
+ const id = accessTokenManager.decode(token)?.value
+ const user = await userRepository.getByUser(id);
+ if (!user) {
+ throwStatusCode(400,"Votre token d'authentification n'est pas le bon");
+ }
+ const ami = await userRepository.getByUser(amiIdUtilisateur)
+ if(!ami) {
+ throwStatusCode(400,'id ami invalide')
+ }
+
+ const profil = await friendRepository.getById(id, amiIdUtilisateur)
+ if(!profil) {
+ throwStatusCode(403,'Il existe aucune relation entre ces deux utilisateurs')
+ }
+
+ return ami
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/friend/unfollowUser.js b/lib/application/use_cases/friend/unfollowUser.js
new file mode 100644
index 0000000..6ac7e66
--- /dev/null
+++ b/lib/application/use_cases/friend/unfollowUser.js
@@ -0,0 +1,20 @@
+'use strict';
+
+const throwStatusCode = require("../utils/throwStatusCode")
+
+module.exports = async (token, amiIdUtilisateur, {accessTokenManager, userRepository, friendRepository}) => {
+ const id = accessTokenManager.decode(token)?.value
+ const user = await userRepository.getByUser(id);
+ if (!user) {
+ throwStatusCode(400,"Votre token d'authentification n'est pas le bon");
+ }
+ const ami = await userRepository.getByUser(amiIdUtilisateur)
+ if(!ami) {
+ throwStatusCode(400,'id ami invalide')
+ }
+ const friend = await friendRepository.removeFriendById(id, amiIdUtilisateur)
+ if(!friend) {
+ throwStatusCode(403,'Il existe aucune relation entre ces deux utilisateurs')
+ }
+ return friend
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/oeuvre/getOeuvre.js b/lib/application/use_cases/oeuvre/getOeuvre.js
new file mode 100644
index 0000000..2a1c07d
--- /dev/null
+++ b/lib/application/use_cases/oeuvre/getOeuvre.js
@@ -0,0 +1,129 @@
+const throwStatusCode = require("../utils/throwStatusCode.js");
+const OeuvrePage = require("../../../domain/model/OeuvrePage.js");
+const reviewSerializer = require("../../../interfaces/serializers/ReviewSerializer.js");
+const fetchArtist = require("../spotify/FetchArtist.js");
+const getAlbum = require("../spotify/getAlbum.js");
+const getTrack = require("../spotify/getTrack.js");
+
+module.exports = async (
+ idOeuvre,
+ userToken,
+ {
+ accessTokenManager,
+ userRepository,
+ spotifyRepository,
+ reviewRepository,
+ likeOeuvreRepository,
+ oeuvreFavRepository,
+ friendRepository,
+ followRepository
+ }
+) => {
+ const idUtilisateur = accessTokenManager.decode(userToken)?.value;
+ const user = await userRepository.getByUser(idUtilisateur);
+ if (!user)
+ throwStatusCode(401, "votre token d'authentification n'est pas le bon");
+
+ let oeuvre;
+
+ try {
+ oeuvre = await getAlbum(idOeuvre, { spotifyRepository });
+ } catch (errorAlbum) {
+ try {
+ oeuvre = await getTrack(idOeuvre, { spotifyRepository });
+ } catch (errorTrack) {
+ throwStatusCode(404, "L'ID de l'oeuvre est introuvable");
+ }
+ }
+
+ const artistIds = oeuvre.artists.map((artist) => artist.id);
+
+ const artists = await Promise.all(
+ artistIds.map(async (id) => {
+ const artist = await fetchArtist(id, { spotifyRepository });
+ artist.doesUserFollow = await followRepository.doesFollows(
+ idUtilisateur,
+ id
+ );
+ return artist;
+ })
+ );
+
+ const doesUserLikes = await likeOeuvreRepository.doesUserLikes(
+ idUtilisateur,
+ idOeuvre
+ );
+ const doesUserFav = await oeuvreFavRepository.oeuvreFavExists(
+ idUtilisateur,
+ idOeuvre
+ );
+
+ oeuvre.likeCount = await likeOeuvreRepository.getLikeCount(idOeuvre);
+ oeuvre.reviewCount = await reviewRepository.getReviewCount(idOeuvre);
+ oeuvre.rating = await reviewRepository.getOeuvreRating(idOeuvre);
+
+ oeuvre?.tracks?.map(async (track) => {
+ track.likeCount = await likeOeuvreRepository.getLikeCount( track.id);
+ track.reviewCount = await reviewRepository.getReviewCount( track.id);
+ track.rating = await reviewRepository.getOeuvreRating( track.id);
+ track.doesUserLike = await likeOeuvreRepository.doesUserLikes(
+ idUtilisateur,
+ track.id
+ );
+ return track;
+ });
+
+ const reviewsByLike = await reviewRepository.getOeuvreReviews(
+ 1,
+ 3,
+ true,
+ false,
+ false,
+ [idOeuvre],
+ idUtilisateur
+ );
+ const reviewsByTime = await reviewRepository.getOeuvreReviews(
+ 1,
+ 3,
+ false,
+ false,
+ false,
+ [idOeuvre],
+ idUtilisateur
+ );
+
+ const reviewsByLikeSeri = await Promise.all(
+ reviewsByLike.map(async (review) => {
+ return reviewSerializer(
+ review,
+ idUtilisateur,
+ undefined,
+ spotifyRepository,
+ reviewRepository,
+ friendRepository
+ );
+ })
+ );
+
+ const reviewsByTimeSeri = await Promise.all(
+ reviewsByTime.map(async (review) => {
+ return reviewSerializer(
+ review,
+ idUtilisateur,
+ undefined,
+ spotifyRepository,
+ reviewRepository,
+ friendRepository
+ );
+ })
+ );
+
+ return new OeuvrePage(
+ oeuvre,
+ artists,
+ reviewsByLikeSeri,
+ reviewsByTimeSeri,
+ doesUserLikes,
+ doesUserFav
+ );
+};
diff --git a/lib/application/use_cases/oeuvre/likeOeuvre.js b/lib/application/use_cases/oeuvre/likeOeuvre.js
new file mode 100644
index 0000000..2e12fed
--- /dev/null
+++ b/lib/application/use_cases/oeuvre/likeOeuvre.js
@@ -0,0 +1,13 @@
+const throwStatusCode = require("../utils/throwStatusCode");
+module.exports = async (userToken, artistId,type, {userRepository,likeOeuvreRepository,accessTokenManager,spotifyRepository}) =>{
+ const id_utilisateur = accessTokenManager.decode(userToken)?.value
+ if(! await userRepository.getByUser(id_utilisateur)) throwStatusCode(401,"votre token d'authentification n'est pas le bon")
+ const oeuvre = spotifyRepository.getOeuvre(artistId,type)
+ if(oeuvre.error) throwStatusCode(oeuvre.error.status,oeuvre.error.message)
+ if(! await likeOeuvreRepository.doesUserLikes(id_utilisateur,artistId)) {
+ await likeOeuvreRepository.like(id_utilisateur,artistId)
+ return true
+ }
+ await likeOeuvreRepository.unlike(id_utilisateur,artistId)
+ return false
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/review/deleteReview.js b/lib/application/use_cases/review/deleteReview.js
new file mode 100644
index 0000000..680b649
--- /dev/null
+++ b/lib/application/use_cases/review/deleteReview.js
@@ -0,0 +1,6 @@
+const throwStatusCode = require("../utils/throwStatusCode");
+module.exports = async (idReview, userToken, {accessTokenManager, userRepository,reviewRepository})=> {
+ const id_utilisateur = accessTokenManager.decode(userToken)?.value
+ if(! await userRepository.getByUser(id_utilisateur)) throwStatusCode(401,"votre token d'authentification n'est pas le bon")
+ if(!await reviewRepository.delete(idReview,id_utilisateur)) throwStatusCode(403,"ce n'est pas votre post")
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/review/getArtistReviews.js b/lib/application/use_cases/review/getArtistReviews.js
new file mode 100644
index 0000000..038bccb
--- /dev/null
+++ b/lib/application/use_cases/review/getArtistReviews.js
@@ -0,0 +1,46 @@
+const throwStatusCode = require("../utils/throwStatusCode");
+const reviewSerializer = require("../../../interfaces/serializers/ReviewSerializer");
+module.exports = async (
+ artistId,
+ userToken,
+ page,
+ pageSize,
+ orderByLike,
+ friendsOnly,
+ { reviewRepository, spotifyRepository, accessTokenManager, friendRepository }
+) => {
+ let id = null;
+ if (userToken) {
+ id = accessTokenManager.decode(userToken)?.value;
+ }
+ const artist = await spotifyRepository.getSpotifyArtist(artistId);
+ if (artist.error) throwStatusCode(artist.error.status, artist.error.message);
+ const albums = await spotifyRepository.getSpotifyArtistSongs(
+ artistId,
+ "album,single"
+ );
+ const album_ids = albums.items.map((album) => album.id);
+ const reviews = await reviewRepository.getOeuvreReviews(
+ page,
+ pageSize,
+ orderByLike,
+ false,
+ friendsOnly,
+ album_ids,
+ id
+ );
+ const serializedReviews = [];
+ reviews.forEach((element) => {
+ serializedReviews.push(
+ reviewSerializer(
+ element,
+ id,
+ undefined,
+ spotifyRepository,
+ reviewRepository,
+ friendRepository
+ )
+ );
+ });
+ return await Promise.all(serializedReviews);
+};
diff --git a/lib/application/use_cases/review/getCountOeuvreReviews.js b/lib/application/use_cases/review/getCountOeuvreReviews.js
new file mode 100644
index 0000000..e5b15d1
--- /dev/null
+++ b/lib/application/use_cases/review/getCountOeuvreReviews.js
@@ -0,0 +1,12 @@
+const throwStatusCode = require("../utils/throwStatusCode");
+module.exports = async (OeuvreId, userToken, {reviewRepository, userRepository, accessTokenManager}) => {
+ let id = null
+ if (userToken) {
+ id = accessTokenManager.decode(userToken)?.value
+ }
+ if(! await userRepository.getByUser(id)) throwStatusCode(401,"votre token d'authentification n'est pas le bon")
+
+ const count = await reviewRepository.getReviewCount(OeuvreId)
+
+ return count
+}
diff --git a/lib/application/use_cases/review/getOeuvreReviews.js b/lib/application/use_cases/review/getOeuvreReviews.js
new file mode 100644
index 0000000..ee1db08
--- /dev/null
+++ b/lib/application/use_cases/review/getOeuvreReviews.js
@@ -0,0 +1,39 @@
+const throwStatusCode = require("../utils/throwStatusCode");
+const reviewSerializer = require("../../../interfaces/serializers/ReviewSerializer");
+module.exports = async (
+ OeuvreId,
+ userToken,
+ page,
+ pageSize,
+ orderByLike,
+ friendsOnly,
+ { reviewRepository, spotifyRepository, accessTokenManager, friendRepository }
+) => {
+ let id = null;
+ if (userToken) {
+ id = accessTokenManager.decode(userToken)?.value;
+ }
+ const reviews = await reviewRepository.getOeuvreReviews(
+ page,
+ pageSize,
+ orderByLike,
+ false,
+ friendsOnly,
+ [OeuvreId],
+ id
+ );
+ const serializedReviews = [];
+ reviews.forEach((element) => {
+ serializedReviews.push(
+ reviewSerializer(
+ element,
+ id,
+ undefined,
+ spotifyRepository,
+ reviewRepository,
+ friendRepository
+ )
+ );
+ });
+ return await Promise.all(serializedReviews);
+};
diff --git a/lib/application/use_cases/review/getReview.js b/lib/application/use_cases/review/getReview.js
new file mode 100644
index 0000000..0f6b47d
--- /dev/null
+++ b/lib/application/use_cases/review/getReview.js
@@ -0,0 +1,51 @@
+const throwStatusCode = require("../utils/throwStatusCode");
+const reviewSerializer = require("../../../interfaces/serializers/ReviewSerializer");
+const getReview = require("./util/getReview");
+module.exports = async (
+ idReview,
+ userToken,
+ page,
+ pageSize,
+ orderByLike,
+ {
+ reviewRepository,
+ spotifyRepository,
+ accessTokenManager,
+ friendRepository,
+ commentRepository,
+ }
+) => {
+ const rawReview = await getReview(idReview, userToken, {
+ accessTokenManager,
+ friendRepository,
+ reviewRepository,
+ });
+ console.log(rawReview);
+ const rawOeuvre = await spotifyRepository.getOeuvre(
+ rawReview.id_oeuvre,
+ rawReview.type
+ );
+ if (rawOeuvre.error)
+ throwStatusCode(rawOeuvre.error.status, rawOeuvre.error.message);
+
+ let id_utilisateur = userToken
+ ? accessTokenManager.decode(userToken)?.value
+ : null;
+ const comments = await commentRepository.getReviewComments(
+ rawReview.id_review,
+ id_utilisateur,
+ false,
+ page,
+ pageSize,
+ orderByLike
+ );
+
+ return reviewSerializer(
+ rawReview,
+ id_utilisateur,
+ comments,
+ spotifyRepository,
+ reviewRepository,
+ friendRepository
+ );
+};
diff --git a/lib/application/use_cases/review/getReviewLikes.js b/lib/application/use_cases/review/getReviewLikes.js
new file mode 100644
index 0000000..1c32011
--- /dev/null
+++ b/lib/application/use_cases/review/getReviewLikes.js
@@ -0,0 +1,12 @@
+const throwStatusCode = require("../utils/throwStatusCode");
+const UserPublic = require("../../../domain/model/UserPublic")
+const getReview = require("./util/getReview")
+
+module.exports = async (reviewId,userToken,page,pageSize,{accessTokenManager,reviewRepository,friendRepository}) =>{
+ const reviewTest = await getReview(reviewId,userToken, {accessTokenManager,friendRepository,reviewRepository})
+ if(userToken) {
+ userToken = accessTokenManager.decode(userToken)?.value
+ }
+ const users = (await reviewRepository.getLikes(userToken,reviewId,page,pageSize)).map(item => new UserPublic(item))
+ return users
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/review/getReviews.js b/lib/application/use_cases/review/getReviews.js
new file mode 100644
index 0000000..a3e1a14
--- /dev/null
+++ b/lib/application/use_cases/review/getReviews.js
@@ -0,0 +1,33 @@
+const reviewSerializer = require("../../../interfaces/serializers/ReviewSerializer");
+module.exports = async (
+ page,
+ pageSize,
+ orderByLike,
+ friendsOnly,
+ userToken,
+ { reviewRepository, spotifyRepository, accessTokenManager, friendRepository }
+) => {
+ if (userToken) userToken = accessTokenManager.decode(userToken)?.value;
+ const rawReviews = await reviewRepository.getReviews(
+ page,
+ pageSize,
+ orderByLike,
+ false,
+ friendsOnly,
+ userToken
+ );
+ const serializedReviews = [];
+ rawReviews.forEach((element) => {
+ serializedReviews.push(
+ reviewSerializer(
+ element,
+ userToken,
+ undefined,
+ spotifyRepository,
+ reviewRepository,
+ friendRepository
+ )
+ );
+ });
+ return await Promise.all(serializedReviews);
+};
diff --git a/lib/application/use_cases/review/getUserReviews.js b/lib/application/use_cases/review/getUserReviews.js
new file mode 100644
index 0000000..6487bd2
--- /dev/null
+++ b/lib/application/use_cases/review/getUserReviews.js
@@ -0,0 +1,50 @@
+const throwStatusCode = require("../utils/throwStatusCode");
+const reviewSerializer = require("../../../interfaces/serializers/ReviewSerializer");
+const { identity } = require("underscore");
+module.exports = async (
+ pseudo,
+ userToken,
+ page,
+ pageSize,
+ orderByLike,
+ {
+ reviewRepository,
+ spotifyRepository,
+ accessTokenManager,
+ friendRepository,
+ userRepository,
+ }
+) => {
+ const testUsers = await userRepository.getByEmailOrPseudo(pseudo, pseudo);
+ if (!testUsers) throwStatusCode(404, "l'utilisateur n'existe pas");
+ let id = null;
+ if (testUsers?.is_private) {
+ let valid = false;
+ if (userToken) {
+ id = accessTokenManager.decode(userToken)?.value;
+ if (await friendRepository.areFriends(id, testUsers.id_utilisateur))
+ valid = true;
+ }
+ if (!valid) throwStatusCode(403, "l'utilisateur est en privé");
+ }
+ const reviews = await reviewRepository.getReviewByUserId(
+ testUsers.id_utilisateur,
+ page,
+ pageSize,
+ orderByLike
+ );
+ const serializedReviews = [];
+ reviews.forEach((element) => {
+ serializedReviews.push(
+ reviewSerializer(
+ element,
+ id,
+ undefined,
+ spotifyRepository,
+ reviewRepository,
+ friendRepository
+ )
+ );
+ });
+ return await Promise.all(serializedReviews);
+};
diff --git a/lib/application/use_cases/review/likeReview.js b/lib/application/use_cases/review/likeReview.js
new file mode 100644
index 0000000..5aed82e
--- /dev/null
+++ b/lib/application/use_cases/review/likeReview.js
@@ -0,0 +1,10 @@
+const throwStatusCode = require("../utils/throwStatusCode");
+module.exports = async (reviewId,userToken,{accessTokenManager,userRepository,reviewRepository}) =>{
+ const id_utilisateur = accessTokenManager.decode(userToken)?.value
+ if(! await userRepository.getByUser(id_utilisateur)) throwStatusCode(401,"votre token d'authentification n'est pas le bon")
+ if(! await reviewRepository.doesUserLikes(id_utilisateur,reviewId)){
+ await reviewRepository.likeReview(id_utilisateur,reviewId)
+ return true
+ }
+ await reviewRepository.unlikeReview(id_utilisateur,reviewId)
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/review/putComment.js b/lib/application/use_cases/review/putComment.js
new file mode 100644
index 0000000..bae5c72
--- /dev/null
+++ b/lib/application/use_cases/review/putComment.js
@@ -0,0 +1,29 @@
+const throwStatusCode = require("../utils/throwStatusCode");
+const getReview = require("./util/getReview");
+module.exports = async (
+ userToken,
+ idReview,
+ description,
+ {
+ userRepository,
+ accessTokenManager,
+ friendRepository,
+ reviewRepository,
+ commentRepository,
+ }
+) => {
+ const id_utilisateur = accessTokenManager.decode(userToken)?.value;
+ if (!(await userRepository.getByUser(id_utilisateur)))
+ throwStatusCode(401, "votre token d'authentification n'est pas le bon");
+ await getReview(idReview, userToken, {
+ accessTokenManager,
+ friendRepository,
+ reviewRepository,
+ });
+ return await commentRepository.persist(
+ idReview,
+ description,
+ id_utilisateur,
+ null
+ );
+};
diff --git a/lib/application/use_cases/review/putReview.js b/lib/application/use_cases/review/putReview.js
new file mode 100644
index 0000000..19f9ecd
--- /dev/null
+++ b/lib/application/use_cases/review/putReview.js
@@ -0,0 +1,48 @@
+const throwStatusCode = require("../utils/throwStatusCode");
+const reviewSerializer = require("../../../interfaces/serializers/ReviewSerializer");
+module.exports = async (
+ idOeuvre,
+ userToken,
+ description,
+ note,
+ type,
+ {
+ accessTokenManager,
+ userRepository,
+ reviewRepository,
+ spotifyRepository,
+ friendRepository,
+ oeuvreRepository,
+ }
+) => {
+ const id_utilisateur = accessTokenManager.decode(userToken)?.value;
+
+ if (!(await userRepository.getByUser(id_utilisateur)))
+ throwStatusCode(401, "votre token d'authentification n'est pas le bon");
+ if (await reviewRepository.getByUserAndId(idOeuvre, id_utilisateur))
+ throwStatusCode(403, "vous avez déjà posté une review");
+ const id_type_review = await reviewRepository.getTypeReviewID(type);
+ if (!id_type_review) throwStatusCode(404, "ce type de review n'existe pas");
+ const rawOeuvre = await spotifyRepository.getOeuvre(idOeuvre, type);
+ if (rawOeuvre.error)
+ throwStatusCode(rawOeuvre.error.status, rawOeuvre.error.message);
+ if (oeuvreRepository.is_oeuvre_relation(idOeuvre)) {
+ console.log(rawOeuvre);
+ }
+ const ReviewRaw = {
+ id_oeuvre: idOeuvre,
+ id_utilisateur,
+ description,
+ note,
+ id_type_review,
+ };
+ const review = await reviewRepository.persist(ReviewRaw);
+ return reviewSerializer(
+ review,
+ id_utilisateur,
+ undefined,
+ spotifyRepository,
+ reviewRepository,
+ friendRepository
+ );
+};
diff --git a/lib/application/use_cases/review/util/getReview.js b/lib/application/use_cases/review/util/getReview.js
new file mode 100644
index 0000000..8998515
--- /dev/null
+++ b/lib/application/use_cases/review/util/getReview.js
@@ -0,0 +1,26 @@
+const throwStatusCode = require("../../utils/throwStatusCode");
+
+module.exports = async (
+ idReview,
+ userToken,
+ { accessTokenManager, friendRepository, reviewRepository }
+) => {
+ const rawReview = await reviewRepository.getById(idReview);
+ if (!rawReview) throwStatusCode(404, "la review n'existe pas");
+
+ if (userToken) {
+ const id = accessTokenManager.decode(userToken)?.value;
+ if (
+ await friendRepository.areFriends(
+ id,
+ rawReview.utilisateur.id_utilisateur
+ )
+ ) {
+ return rawReview;
+ }
+ }
+ if (!rawReview.utilisateur.is_private) {
+ return rawReview;
+ }
+ throwStatusCode(403, "l'utilisateur est en privé");
+};
diff --git a/lib/application/use_cases/security/GetAccessToken.js b/lib/application/use_cases/security/GetAccessToken.js
index 09fdc08..9a5f9f4 100644
--- a/lib/application/use_cases/security/GetAccessToken.js
+++ b/lib/application/use_cases/security/GetAccessToken.js
@@ -1,15 +1,15 @@
'use strict';
const throwStatusCode = require("../utils/throwStatusCode")
const bcrypt = require("bcrypt");
+const userPublic = require("../../../domain/model/UserPublic")
module.exports = async (email, password, { userRepository, accessTokenManager }) => {
const user = await userRepository.getByIdent(email);
if (!user || !await bcrypt.compare(password,user.password)) {
throwStatusCode(401,'Bad credentials')
}
- return accessTokenManager.generate({
- sub: 'my-sub', // needs to match definition above
- value: user.id, // this is a custom key I used, it could be named anything. Value should be a way to authenticate the user
- aud: 'urn:audience:test', // needs to match definition above
- iss: 'urn:issuer:test' // needs to match definition above
- });
+ return {
+ user : new userPublic(user),
+ token: accessTokenManager.generate(user)
+ }
+
};
diff --git a/lib/application/use_cases/security/VerifyAccessToken.js b/lib/application/use_cases/security/VerifyAccessToken.js
deleted file mode 100644
index c33f20b..0000000
--- a/lib/application/use_cases/security/VerifyAccessToken.js
+++ /dev/null
@@ -1,9 +0,0 @@
-'use strict';
-
-module.exports = (accessToken, { accessTokenManager }) => {
- const decoded = accessTokenManager.decode(accessToken);
- if (!decoded) {
- throw new Error('Invalid access token');
- }
- return { uid: decoded.uid };
-};
diff --git a/lib/application/use_cases/spotify/FetchArtist.js b/lib/application/use_cases/spotify/FetchArtist.js
new file mode 100644
index 0000000..33c786f
--- /dev/null
+++ b/lib/application/use_cases/spotify/FetchArtist.js
@@ -0,0 +1,15 @@
+const SerializeArtist = require("../../../interfaces/serializers/ArtistSerializer")
+const throwStatusCode = require("../utils/throwStatusCode")
+
+module.exports = async (id, {spotifyRepository}) =>{
+ let artistInfo = {}
+ try{
+ artistInfo = await spotifyRepository.getSpotifyArtist(id)
+ }
+ catch(error){
+ throwStatusCode(400, `l'id : ${id} n'existe pas`)
+ }
+
+ const artist = SerializeArtist(artistInfo) // Formatage de l'objet
+ return artist
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/spotify/FetchArtistSongs.js b/lib/application/use_cases/spotify/FetchArtistSongs.js
new file mode 100644
index 0000000..b766109
--- /dev/null
+++ b/lib/application/use_cases/spotify/FetchArtistSongs.js
@@ -0,0 +1,44 @@
+const SerializeAlbum = require("../../../interfaces/serializers/AlbumSerializer")
+const throwStatusCode = require("../utils/throwStatusCode")
+
+module.exports = async (id, filter, limit, { spotifyRepository }) => {
+ const album = "album"
+ const single = "single"
+ const compilation = "compilation"
+ const appearsOn = "appears_on"
+
+ let returnValue = []
+ let artistSongs = {}
+
+ try{
+ artistSongs = await spotifyRepository.getSpotifyArtistSongs(id, filter, limit)
+ }
+ catch(error){
+ throwStatusCode(400, `l'id : ${id} n'existe pas`)
+ }
+
+ const filterTab = filter.split(',')
+
+ // Recuperation selon le(s) filtre(s) et serialisation
+
+ //recupere par defaut le include_groups : appears_on avec album
+ const albumRaw = filterTab.includes(album) ? artistSongs?.items?.filter(item => item?.album_group === album) || [] : [];
+ const albumSerialized = albumRaw.length > 0 ? albumRaw.map(item => SerializeAlbum(item)) : [];
+
+ const singleRaw = filterTab.includes(single) ? artistSongs?.items?.filter(item => item?.album_group === single) || [] : [];
+ const singleSerialized = singleRaw.length > 0 ? singleRaw.map(item => SerializeAlbum(item)) : [];
+
+ const compilationRaw = filterTab.includes(compilation) ? artistSongs?.items?.filter(item => item?.album_group === compilation) || [] : [];
+ const compilationSerialized = compilationRaw.length > 0 ? compilationRaw.map(item => SerializeAlbum(item)) : [];
+
+ // autre champ utilise pour appearsOn : album_group
+ const appearsOnRaw = filterTab.includes(appearsOn) ? artistSongs?.items?.filter(item => item?.album_group === appearsOn) || [] : [];
+ const appearsOnialized = appearsOnRaw.length > 0 ? appearsOnRaw.map(item => SerializeAlbum(item)) : [];
+
+ returnValue.push(...albumSerialized)
+ returnValue.push(...singleSerialized)
+ returnValue.push(...compilationSerialized)
+ returnValue.push(...appearsOnialized)
+
+ return returnValue
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/spotify/GetToken.js b/lib/application/use_cases/spotify/GetToken.js
new file mode 100644
index 0000000..57962f7
--- /dev/null
+++ b/lib/application/use_cases/spotify/GetToken.js
@@ -0,0 +1,10 @@
+const throwStatusCode = require("../utils/throwStatusCode")
+module.exports = async (code,{spotifyRepository}) => {
+ const {access_token, refresh_token,error} = await spotifyRepository.getToken(code)
+ if(error)
+ throwStatusCode(400,error)
+ return {
+ token:access_token,
+ refresh_token
+ }
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/spotify/RefreshToken.js b/lib/application/use_cases/spotify/RefreshToken.js
new file mode 100644
index 0000000..f7d2558
--- /dev/null
+++ b/lib/application/use_cases/spotify/RefreshToken.js
@@ -0,0 +1,19 @@
+module.exports = async (user,instant_refresh,{spotifyRepository,userRepository}) => {
+ const action = async ()=>{
+ const {access_token} = await spotifyRepository.refreshToken(user.refresh_token)
+ user.token = access_token
+ userRepository.updateUser(user)
+ }
+ if(instant_refresh){
+ try{
+ await action()
+ }catch(e){
+ user.refresh_token = null
+ user.token = null
+ await userRepository.updateUser(user)
+ }
+ }
+ setInterval(async ()=>{
+ action()
+ },3500*1000)
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/spotify/Search.js b/lib/application/use_cases/spotify/Search.js
index e1e8b70..ccea3cd 100644
--- a/lib/application/use_cases/spotify/Search.js
+++ b/lib/application/use_cases/spotify/Search.js
@@ -1,27 +1,42 @@
const SerializeTrack = require("../../../interfaces/serializers/TrackSerializer")
const SerializeAlbum = require("../../../interfaces/serializers/AlbumSerializer")
const SerializeArtist = require("../../../interfaces/serializers/ArtistSerializer")
+const SerializeSearchItem = require("../../../interfaces/serializers/SerializeSearchItem")
const MAX_USER = 3
-module.exports = async (query,filter, limit,allow_user, {spotifyRepository, userRepository}) =>{
+module.exports = async (query,filter, limit, {spotifyRepository, userRepository}) =>{
let limitSize = limit
let users = []
- if(allow_user){
-
+ filter = filter.split(",")
+ if(filter.includes("user")){
+ filter = filter.filter(item => item !== "user");
users = await userRepository.getUsersByPseudo(query,MAX_USER)
+ console.log(users)
limitSize -= users.length
}
- const searchListRaw = await spotifyRepository.getSpotifySearchList(query, filter, limitSize)
+
+ const searchListRaw = filter.length>0
+ ? await spotifyRepository.getSpotifySearchList(query, filter.join(","), limitSize)
+ : {}
let returnValue = []
+
+ // Formatage des objets
const tracks = searchListRaw?.tracks ?
searchListRaw?.tracks?.items.map(item => SerializeTrack(item)) : []
+
const albums = searchListRaw?.albums ?
searchListRaw?.albums?.items.map(item => SerializeAlbum(item)) : []
const artists = searchListRaw?.artists ?
searchListRaw?.artists?.items.map(item => SerializeArtist(item)) : []
+ if(artists[0])
+ artists[0].popularity = 101
+
returnValue.push(...tracks)
returnValue.push(...albums)
returnValue.push(...artists)
returnValue.sort((item1,item2) => (item2.popularity - item1.popularity))
+ if(returnValue.length> limitSize)
+ returnValue = returnValue.splice(0,limitSize)
returnValue.push(...users)
- return returnValue
+
+ return returnValue.map(item => SerializeSearchItem(item))
}
\ No newline at end of file
diff --git a/lib/application/use_cases/spotify/getAlbum.js b/lib/application/use_cases/spotify/getAlbum.js
new file mode 100644
index 0000000..224778b
--- /dev/null
+++ b/lib/application/use_cases/spotify/getAlbum.js
@@ -0,0 +1,9 @@
+const SerializeAlbum = require("../../../interfaces/serializers/AlbumSerializer")
+const throwStatusCode = require("../utils/throwStatusCode");
+
+module.exports = async (id, {spotifyRepository}) =>{
+ const albumInfo = await spotifyRepository.getSpotifyAlbums(id)
+ if(albumInfo.error)
+ throwStatusCode(albumInfo.error.status,albumInfo.error.message)
+ return SerializeAlbum(albumInfo)
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/spotify/getSearchFilters.js b/lib/application/use_cases/spotify/getSearchFilters.js
new file mode 100644
index 0000000..eca493b
--- /dev/null
+++ b/lib/application/use_cases/spotify/getSearchFilters.js
@@ -0,0 +1,20 @@
+module.exports = () => {
+ return [
+ {
+ label: 'Musique',
+ id: 'track'
+ },
+ {
+ label: 'Artiste',
+ id: 'artist'
+ },
+ {
+ label: 'Album',
+ id: 'album'
+ },
+ {
+ label: 'Utilisateur',
+ id: 'user'
+ },
+ ]
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/spotify/getTrack.js b/lib/application/use_cases/spotify/getTrack.js
new file mode 100644
index 0000000..e8d73bc
--- /dev/null
+++ b/lib/application/use_cases/spotify/getTrack.js
@@ -0,0 +1,8 @@
+const SerializeTrack = require("../../../interfaces/serializers/TrackSerializer")
+const throwStatusCode = require("../utils/throwStatusCode")
+module.exports = async (id, {spotifyRepository}) =>{
+ const trackInfo = await spotifyRepository.getSpotifyTracks(id)
+ if(trackInfo.error)
+ throwStatusCode(trackInfo.error.status,trackInfo.error.message)
+ return SerializeTrack(trackInfo)
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/user/AuthWithSpotify.js b/lib/application/use_cases/user/AuthWithSpotify.js
new file mode 100644
index 0000000..ee3c53e
--- /dev/null
+++ b/lib/application/use_cases/user/AuthWithSpotify.js
@@ -0,0 +1,52 @@
+'use strict';
+
+const User = require('../../../domain/model/User');
+const throwStatusCode = require("../utils/throwStatusCode")
+const crypto = require("crypto");
+const bcrypt = require("bcrypt");
+module.exports = async (spotify_code, callback, { userRepository,spotifyRepository,accessTokenManager}) => {
+ const {access_token, refresh_token,error} = await spotifyRepository.getToken(spotify_code,callback)
+ if(error){
+ throwStatusCode(400,error.message)
+ }
+ const {email,display_name,images} = await spotifyRepository.getAccountData(access_token)
+ const image = images?.at(-1)?.url
+ const userTest = await userRepository.getByEmailOrPseudo(email,email)
+ if(userTest?.confirmed && userTest?.refresh_token){
+ userTest.token = refresh_token
+ userTest.refresh_token = refresh_token
+ await userRepository.updateUser(userTest)
+ return {
+ email : email,
+ token: accessTokenManager.generate(userTest)
+ }
+ }
+ if(!userTest){
+ const confirm_token = crypto.randomBytes(16).toString('hex')
+ const userRaw = {
+ email,
+ alias: display_name ? display_name : null,
+ photo: image ? image : null,
+ confirmed:false,
+ token: access_token,
+ auth_with_spotify: true,
+ refresh_token,
+ confirm_token
+ }
+ const user = new User(
+ userRaw);
+ await userRepository.persist(user)
+ setTimeout(()=>{
+ userRepository.removeUserByConfirmToken(confirm_token)
+ },3600*1000*24)
+ return {
+ confirmToken: confirm_token,
+ }
+ }
+ if(!userTest.auth_with_spotify){
+ throwStatusCode(403, 'un compte existe déjà avec ce mail')
+ }
+ return {
+ confirmToken: userTest.confirm_token
+ }
+};
diff --git a/lib/application/use_cases/user/CompleteAccount.js b/lib/application/use_cases/user/CompleteAccount.js
new file mode 100644
index 0000000..5a5cdc6
--- /dev/null
+++ b/lib/application/use_cases/user/CompleteAccount.js
@@ -0,0 +1,34 @@
+'use strict';
+
+
+const throwStatusCode = require("../utils/throwStatusCode")
+const UserPublic = require("../../../domain/model/UserPublic")
+
+module.exports = async (pseudo,alias, bio, photo,confirmToken, { userRepository,documentRepository, accessTokenManager }) => {
+ const userTest = await userRepository.getByEmailOrPseudo(pseudo,pseudo)
+ if(userTest){
+ throwStatusCode(403,'Pseudo déjà existant')
+ }
+ alias = alias ? alias : pseudo
+ const user = await userRepository.getByConfirmToken(confirmToken);
+ if(!user) {
+ throwStatusCode(400,'Token invalide')
+ }
+ user.alias = alias
+ user.pseudo = pseudo
+ user.bio = bio
+ user.confirm_token = null
+ user.confirmed = true
+ if(user.photo_temporaire && photo){
+ documentRepository.deleteFile(user.photo_temporaire)
+ user.photo_temporaire = photo
+ user.photo = photo
+ }
+ await userRepository.updateUser(user)
+ return {
+ user: new UserPublic(user),
+ token: accessTokenManager.generate(user)
+ }
+
+
+};
diff --git a/lib/application/use_cases/user/CreateUser.js b/lib/application/use_cases/user/CreateUser.js
index afccae1..17bfd67 100644
--- a/lib/application/use_cases/user/CreateUser.js
+++ b/lib/application/use_cases/user/CreateUser.js
@@ -1,31 +1,106 @@
'use strict';
const User = require('../../../domain/model/User');
-const bcrypt = require("bcrypt");
-const etatsEnum = require('../../../domain/model/utils/EtatsEnum')
-const rolesEnum = require('../../../domain/model/utils/RolesEnum')
const throwStatusCode = require("../utils/throwStatusCode")
-module.exports = async (pseudo, email,alias, bio, password,spotifyToken, { userRepository }) => {
- password = await bcrypt.hash(password,10)
- if(!password) {
- throwStatusCode('500','Internal server error')
- }
- const userTest = await userRepository.getByEmailOrPseudo(email,pseudo)
- if(userTest){
- throwStatusCode('403','Email ou Pseudo déjà existant')
- }
- const user = new User(
- null,
- pseudo,
- email,
- alias,
- bio,
- password,
- spotifyToken,
- rolesEnum.UTILISATEUR,
- etatsEnum.LIBRE);
- return userRepository.persist(user)
+const crypto = require("crypto");
+const bcrypt = require("bcrypt");
+module.exports = async (email,password, { userRepository,mailRepository}) => {
+ const userTest = await userRepository.getByEmailOrPseudo(email,email)
+ if(userTest){
+ throwStatusCode(403,'Email déjà existant')
+ }
+ password = await bcrypt.hash(password,10)
+ if(!password) {
+ throwStatusCode('500','Internal server error')
+ }
+ const confirm_token = Math.floor(Math.random() * (99999 - 10000) + 10000)
+ const userRaw = {
+ email,
+ confirmed:false,
+ password,
+ confirm_token
+ }
+ let user = new User(
+ userRaw);
+ user = await userRepository.persist(user)
+ if (!user) {
+ throwStatusCode(400, 'Ce compte n\'a pas pu être créé. Veuillez réessayer plus tard.')
+ }
+ const mailOptions = {
+ from: process.env.MAILER_EMAIL,
+ to: email,
+ subject: 'Votre token de confirmation pour votre connexion',
+ html: `
+
+
+
+
+
+ Votre token de confirmation
+
+
+
+
+
+
+
+
Votre token de confirmation
+
Voici votre token de confirmation pour votre prochaine connexion sur Solimbo :
+
+
Utilisez ce token pour compléter votre inscription sur notre site.
+
Se connecter
+
+
+
+ `
+ };
+ await mailRepository.send(mailOptions)
+ setTimeout(()=>{
+ userRepository.removeUserByConfirmToken(confirm_token)
+ },60*5*1000)
+ return user
};
diff --git a/lib/application/use_cases/user/changePrivateStatus.js b/lib/application/use_cases/user/changePrivateStatus.js
new file mode 100644
index 0000000..fd262ec
--- /dev/null
+++ b/lib/application/use_cases/user/changePrivateStatus.js
@@ -0,0 +1,12 @@
+'use strict';
+
+const throwStatusCode = require("../utils/throwStatusCode")
+
+module.exports = async (token, {accessTokenManager, userRepository}) => {
+ const id = accessTokenManager.decode(token)?.value
+ const user = await userRepository.changePrivateStatus(id)
+ if (!user) {
+ throwStatusCode(400,"Votre token d'authentification n'est pas le bon");
+ }
+ return user
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/user/follow.js b/lib/application/use_cases/user/follow.js
new file mode 100644
index 0000000..823ac37
--- /dev/null
+++ b/lib/application/use_cases/user/follow.js
@@ -0,0 +1,14 @@
+const throwStatusCode = require("../utils/throwStatusCode");
+module.exports = async (userToken, artistId, {userRepository,followRepository,accessTokenManager,spotifyRepository}) =>{
+ const id = accessTokenManager.decode(userToken)?.value
+ if(! await userRepository.getByUser(id)) throwStatusCode(401,"votre token d'authentification n'est pas le bon")
+ const artist = await spotifyRepository.getSpotifyArtist(artistId)
+ if(artist.error) throwStatusCode(artist.error.status,artist.error.message)
+ if(! await followRepository.doesFollows(id,artistId)) {
+ followRepository.follow(id,artistId)
+ return true
+ }
+ followRepository.unfollow(id,artistId)
+ return false
+
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/user/getOeuvresFav.js b/lib/application/use_cases/user/getOeuvresFav.js
new file mode 100644
index 0000000..9c0d9b8
--- /dev/null
+++ b/lib/application/use_cases/user/getOeuvresFav.js
@@ -0,0 +1,10 @@
+const throwStatusCode = require("../utils/throwStatusCode");
+
+module.exports = async (userToken, {userRepository, oeuvreFavRepository, accessTokenManager}) =>{
+ const idUtilisateur = accessTokenManager.decode(userToken)?.value
+ if(! await userRepository.getByUser(idUtilisateur)) throwStatusCode(401,"votre token d'authentification n'est pas le bon")
+
+ let oeuvresFav = []
+ oeuvresFav = await oeuvreFavRepository.getOeuvresFav(idUtilisateur)
+ return oeuvresFav
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/user/getPage.js b/lib/application/use_cases/user/getPage.js
new file mode 100644
index 0000000..285e790
--- /dev/null
+++ b/lib/application/use_cases/user/getPage.js
@@ -0,0 +1,91 @@
+const throwStatusCode = require("../utils/throwStatusCode");
+const oeuvreSerializer = require("../../../interfaces/serializers/OeuvreSerializer");
+const UserPublic = require("../../../domain/model/UserPublic");
+const reviewSerializer = require("../../../interfaces/serializers/ReviewSerializer");
+module.exports = async (
+ id_utilisateur,
+ page,
+ pageSize,
+ orderByLike,
+ user_token,
+ {
+ userRepository,
+ friendRepository,
+ oeuvreFavRepository,
+ reviewRepository,
+ accessTokenManager,
+ spotifyRepository,
+ }
+) => {
+ const current_user = await userRepository.getByUser(
+ accessTokenManager.decode(user_token)?.value
+ );
+
+ if (!current_user)
+ throwStatusCode(401, "votre token d'authentification n'est pas le bon");
+ const selected_user = await userRepository.getByUser(id_utilisateur);
+ if (!selected_user) throwStatusCode(404, "l'utilisateur n'existe pas");
+ const isCurrent = id_utilisateur == current_user.id_utilisateur;
+ const doesFollows = await friendRepository.doesFollows(
+ id_utilisateur,
+ current_user.id_utilisateur
+ );
+ const relation = await friendRepository.getFollowInfo(
+ id_utilisateur,
+ current_user.id_utilisateur
+ );
+ if (selected_user.is_private && !doesFollows) {
+ return {
+ user: new UserPublic(selected_user),
+ forbidden: true,
+ relation,
+ };
+ }
+
+ const idOeuvres = await oeuvreFavRepository.getOeuvresFav(id_utilisateur);
+ const reviewsRaw = await reviewRepository.getReviewByUserId(
+ id_utilisateur,
+ page,
+ pageSize,
+ orderByLike
+ );
+
+ const oeuvresPromise = Promise.all(
+ idOeuvres.map(async (oeuvre) => {
+ const SpotifyOeuvre = await spotifyRepository.getOeuvre(
+ oeuvre.id_oeuvre,
+ oeuvre.type
+ );
+ SpotifyOeuvre.rating = await reviewRepository.getOeuvreRating(
+ SpotifyOeuvre.id
+ );
+ return oeuvreSerializer(SpotifyOeuvre, oeuvre.type);
+ })
+ );
+
+ const reviewsPromise = Promise.all(
+ reviewsRaw.map(async (review) => {
+ return reviewSerializer(
+ review,
+ id_utilisateur,
+ undefined,
+ spotifyRepository,
+ reviewRepository,
+ friendRepository
+ );
+ })
+ );
+
+ const [oeuvres, reviews] = await Promise.all([
+ oeuvresPromise,
+ reviewsPromise,
+ ]);
+ return {
+ user: new UserPublic(selected_user),
+ forbidden: false,
+ isCurrent,
+ relation,
+ oeuvres,
+ reviews,
+ };
+};
diff --git a/lib/application/use_cases/user/getUserByConfirmToken.js b/lib/application/use_cases/user/getUserByConfirmToken.js
new file mode 100644
index 0000000..070e217
--- /dev/null
+++ b/lib/application/use_cases/user/getUserByConfirmToken.js
@@ -0,0 +1,5 @@
+const UserPublic = require("../../../domain/model/UserPublic")
+module.exports = async (confirmToken,{userRepository}) =>{
+ const user = await userRepository.getByConfirmToken(confirmToken)
+ return user ? new UserPublic(user) : null
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/user/getUserByPseudo.js b/lib/application/use_cases/user/getUserByPseudo.js
new file mode 100644
index 0000000..9f34bb3
--- /dev/null
+++ b/lib/application/use_cases/user/getUserByPseudo.js
@@ -0,0 +1,7 @@
+const UserPublic = require("../../../domain/model/UserPublic")
+module.exports = async (pseudo,{userRepository}) =>{
+ const user = await userRepository.getByEmailOrPseudo(pseudo,pseudo)
+ console.log(!!user)
+ console.log(user)
+ return user ? new UserPublic(user) : null
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/user/modifyProfile.js b/lib/application/use_cases/user/modifyProfile.js
new file mode 100644
index 0000000..afd6232
--- /dev/null
+++ b/lib/application/use_cases/user/modifyProfile.js
@@ -0,0 +1,36 @@
+"use strict";
+const isImage = require("../utils/isImage");
+const throwStatusCode = require("../utils/throwStatusCode");
+const UserPublic = require("../../../domain/model/UserPublic");
+module.exports = async (
+ file,
+ pseudo,
+ bio,
+ alias,
+ isPrivate,
+ token,
+ { accessTokenManager, userRepository, documentRepository }
+) => {
+ const id = accessTokenManager.decode(token)?.value;
+ const user = await userRepository.getByUser(id);
+ if (!user)
+ throwStatusCode(401, "votre token d'authentification n'est pas le bon");
+ if (file) {
+ if (!isImage(file))
+ throwStatusCode(415, "le fichier fourni n'est pas une image");
+ const previewPath = user.photo;
+ if (previewPath) {
+ await documentRepository.deleteFile(previewPath);
+ }
+ const path = await documentRepository.uploadFile("upload", file);
+ if (!path) throwStatusCode(500, "internal server error");
+ user.photo = path;
+ }
+ if (pseudo) user.pseudo = pseudo;
+ if (bio) user.bio = bio;
+ if (alias) user.alias = alias;
+ if (isPrivate !== undefined) user.is_private = isPrivate;
+
+ await userRepository.updateUser(user);
+ return new UserPublic(user);
+};
diff --git a/lib/application/use_cases/user/oeuvreFav.js b/lib/application/use_cases/user/oeuvreFav.js
new file mode 100644
index 0000000..99887e5
--- /dev/null
+++ b/lib/application/use_cases/user/oeuvreFav.js
@@ -0,0 +1,23 @@
+const throwStatusCode = require("../utils/throwStatusCode");
+const getAlbum = require("../spotify/getAlbum");
+const getTrack = require("../spotify/getTrack");
+const { error } = require("@hapi/joi/lib/base");
+
+module.exports = async (userToken, idOeuvre, type, {userRepository, oeuvreFavRepository, accessTokenManager,spotifyRepository}) =>{
+ const idUtilisateur = accessTokenManager.decode(userToken)?.value
+ if(! await userRepository.getByUser(idUtilisateur)) throwStatusCode(401,"votre token d'authentification n'est pas le bon")
+
+ const oeuvre = spotifyRepository.getOeuvre(idOeuvre, type)
+ if(oeuvre.error)
+ throwStatusCode(oeuvre.error.status,oeuvre.error.message)
+
+ if (!(await oeuvreFavRepository.oeuvreFavExists(idUtilisateur, idOeuvre))){
+
+ if (!(await oeuvreFavRepository.ajoutPossible(idUtilisateur))) throwStatusCode(403,"Vous avez atteints le nombre maximal d'oeuvres favorites")
+ await oeuvreFavRepository.addOeuvrefav(idUtilisateur,idOeuvre,type)
+ return true
+ }
+
+ await oeuvreFavRepository.deleteOeuvrefav(idUtilisateur,idOeuvre)
+ return false
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/user/resetPassword.js b/lib/application/use_cases/user/resetPassword.js
new file mode 100644
index 0000000..7fb6c64
--- /dev/null
+++ b/lib/application/use_cases/user/resetPassword.js
@@ -0,0 +1,21 @@
+'use strict';
+
+const User = require('../../../domain/model/User');
+const bcrypt = require("bcrypt");
+const rolesEnum = require('../../../domain/model/utils/RolesEnum')
+const throwStatusCode = require("../utils/throwStatusCode")
+const crypto = require("crypto");
+module.exports = async (password,resetToken,{userRepository}) => {
+ const user = await userRepository.getByResetToken(resetToken)
+ if(!user) {
+ throwStatusCode(400,'Token invalide')
+ }
+ password = await bcrypt.hash(password,10)
+ if(!password) {
+ throwStatusCode('500','Internal server error')
+ }
+ user.reset_token = null
+ user.password = password
+ await userRepository.updateUser(user)
+ return user
+};
diff --git a/lib/application/use_cases/user/sendResetEmail.js b/lib/application/use_cases/user/sendResetEmail.js
new file mode 100644
index 0000000..09166ce
--- /dev/null
+++ b/lib/application/use_cases/user/sendResetEmail.js
@@ -0,0 +1,22 @@
+'use strict';
+const crypto = require("crypto");
+module.exports = async (email,{userRepository ,mailRepository}) => {
+ const user = await userRepository.getByEmailOrPseudo(email,email)
+ if(!user || !user.confirmed) return false
+ const reset_token = Math.floor(Math.random() * (99999 - 10000) + 10000)
+ user.reset_token = reset_token
+ await userRepository.updateUser(user)
+ const mailOptions = {
+ from: process.env.MAILER_EMAIL,
+ to: "réinitialisation de votre compte",
+ subject: 'reinitialisation de votre mot de passe',
+ text: reset_token
+ };
+ await mailRepository.send(mailOptions)
+
+ setTimeout(()=>{
+ delete user.reset_token
+ userRepository.updateUser(user)
+ },60*5*1000)
+ return true
+};
diff --git a/lib/application/use_cases/user/uploadPreview.js b/lib/application/use_cases/user/uploadPreview.js
new file mode 100644
index 0000000..13dfa18
--- /dev/null
+++ b/lib/application/use_cases/user/uploadPreview.js
@@ -0,0 +1,16 @@
+'use strict';
+const isImage = require("../utils/isImage")
+const throwStatusCode = require("../utils/throwStatusCode")
+module.exports = async (file,token,{accessTokenManager, userRepository,documentRepository}) => {
+ if(!isImage(file)) throwStatusCode(415,"le fichier fourni n'est pas une image")
+ const id = accessTokenManager.decode(token)?.value
+ if(! await userRepository.getByUser(id)) throwStatusCode(401,"votre token d'authentification n'est pas le bon")
+ const previewPath = await userRepository.getPreviewPath(id)
+ if(previewPath) {
+ documentRepository.deleteFile(previewPath)
+ }
+ const path = await documentRepository.uploadFile('upload',file)
+ if(! path) throwStatusCode(500, "internal server error")
+ userRepository.addPreviewPath(id,path)
+ return path
+};
\ No newline at end of file
diff --git a/lib/application/use_cases/utils/isImage.js b/lib/application/use_cases/utils/isImage.js
new file mode 100644
index 0000000..3df302c
--- /dev/null
+++ b/lib/application/use_cases/utils/isImage.js
@@ -0,0 +1,5 @@
+const acceptedHeaders = ['image/png','image/jpeg']
+module.exports = (file) => {
+ const header = file?.hapi?.headers['content-type']
+ return acceptedHeaders.includes(header) && file?.hapi?.filename && file._data
+}
\ No newline at end of file
diff --git a/lib/application/use_cases/utils/throwStatusCode.js b/lib/application/use_cases/utils/throwStatusCode.js
index c732135..e2eb250 100644
--- a/lib/application/use_cases/utils/throwStatusCode.js
+++ b/lib/application/use_cases/utils/throwStatusCode.js
@@ -1,5 +1,6 @@
module.exports = (code, message) => {
- const error = new Error(message)
+ const error = new Error(message || 'error')
+ console.log(error)
error.code = code
throw error
}
\ No newline at end of file
diff --git a/lib/domain/entity/ArtistEntity.js b/lib/domain/entity/ArtistEntity.js
new file mode 100644
index 0000000..be8dffb
--- /dev/null
+++ b/lib/domain/entity/ArtistEntity.js
@@ -0,0 +1,9 @@
+const Joi = require('joi')
+
+const getArtist = Joi.object().keys({
+ id: Joi.string().max(50).required()
+})
+
+module.exports = {
+ getArtist
+}
\ No newline at end of file
diff --git a/lib/domain/entity/CommentEntity.js b/lib/domain/entity/CommentEntity.js
new file mode 100644
index 0000000..9504280
--- /dev/null
+++ b/lib/domain/entity/CommentEntity.js
@@ -0,0 +1,29 @@
+const Joi = require('joi')
+const getCommentParams = Joi.object().keys({
+ id: Joi.string().max(50).required()
+})
+const deleteCommentParams = Joi.object().keys({
+ id: Joi.string().max(50).required()
+})
+const likeCommentParams = Joi.object().keys({
+ id: Joi.string().max(50).required()
+})
+const putCommentParams = Joi.object().keys({
+ id: Joi.string().max(50).required()
+})
+const putCommentPayload = Joi.object().keys({
+ description: Joi.string().max(1500).required()
+})
+const getCommentQuery = Joi.object().keys({
+ page: Joi.number().integer().min(1).required(),
+ pageSize: Joi.number().integer().min(1).required(),
+ orderByLike: Joi.boolean()
+})
+module.exports = {
+ getCommentParams,
+ deleteCommentParams,
+ likeCommentParams,
+ putCommentPayload,
+ putCommentParams,
+ getCommentQuery
+}
\ No newline at end of file
diff --git a/lib/domain/entity/OeuvreEntity.js b/lib/domain/entity/OeuvreEntity.js
new file mode 100644
index 0000000..4c50b07
--- /dev/null
+++ b/lib/domain/entity/OeuvreEntity.js
@@ -0,0 +1,21 @@
+const Joi = require('joi')
+
+const likeOeuvre = Joi.object().keys({
+ type: Joi
+ .string()
+ .required()
+ .custom((value, helpers) => {
+ const allowedValues = ["track", "album", "artist","single","compilation"]
+ return allowedValues.includes(value) ? value : helpers.error('any.invalid')
+ }),
+ id: Joi.string().max(50).required()
+})
+
+const getOeuvre = Joi.object().keys({
+ id: Joi.string().min(1).required()
+})
+
+module.exports = {
+ likeOeuvre,
+ getOeuvre
+}
\ No newline at end of file
diff --git a/lib/domain/entity/ReviewEntity.js b/lib/domain/entity/ReviewEntity.js
new file mode 100644
index 0000000..7373509
--- /dev/null
+++ b/lib/domain/entity/ReviewEntity.js
@@ -0,0 +1,103 @@
+const Joi = require("joi");
+const putReview = Joi.object().keys({
+ idOeuvre: Joi.string().min(1).max(50).required(),
+ description: Joi.string().min(1).max(1500).required(),
+ note: Joi.number().greater(-1).less(6).required(),
+ type: Joi.string()
+ .required()
+ .custom((value, helpers) => {
+ const allowedValues = [
+ "track",
+ "album",
+ "artist",
+ "single",
+ "compilation",
+ ];
+ return allowedValues.includes(value)
+ ? value
+ : helpers.error("any.invalid");
+ }),
+});
+const deleteReview = Joi.object().keys({
+ idReview: Joi.string().min(1).max(50).required(),
+});
+
+const getReviewParams = Joi.object().keys({
+ id: Joi.string().min(1).max(50).required(),
+});
+const getReviewQuery = Joi.object().keys({
+ page: Joi.number().integer().min(1).required(),
+ pageSize: Joi.number().integer().min(1).required(),
+ orderByLike: Joi.boolean(),
+});
+const getReviews = Joi.object().keys({
+ page: Joi.number().integer().min(1).required(),
+ pageSize: Joi.number().integer().min(1).required(),
+ orderByLike: Joi.boolean(),
+ friendsOnly: Joi.boolean(),
+});
+
+const likeReviewParams = Joi.object().keys({
+ id: Joi.number().required(),
+});
+
+const likeReviewQuery = Joi.object().keys({
+ page: Joi.number().integer().min(1).required(),
+ pageSize: Joi.number().integer().min(1).required(),
+});
+
+const userReviewParams = Joi.object().keys({
+ id: Joi.string().max(50).required(),
+});
+
+const userReviewQuery = Joi.object().keys({
+ page: Joi.number().integer().min(1).required(),
+ pageSize: Joi.number().integer().min(1).required(),
+ orderByLike: Joi.boolean(),
+});
+
+const oeuvreReviewParams = Joi.object().keys({
+ id: Joi.string().max(50).required(),
+});
+
+const oeuvreReviewQuery = Joi.object().keys({
+ page: Joi.number().integer().min(1).required(),
+ pageSize: Joi.number().integer().min(1).required(),
+ orderByLike: Joi.boolean(),
+ friendsOnly: Joi.boolean(),
+});
+
+const artistReviewParams = Joi.object().keys({
+ id: Joi.string().max(50).required(),
+});
+
+const artistReviewQuery = Joi.object().keys({
+ page: Joi.number().integer().min(1).required(),
+ pageSize: Joi.number().integer().min(1).required(),
+ orderByLike: Joi.boolean(),
+ friendsOnly: Joi.boolean(),
+});
+const putCommentParams = Joi.object().keys({
+ id: Joi.string().max(50).required(),
+});
+
+const putCommentPayload = Joi.object().keys({
+ description: Joi.string().max(1500).required(),
+});
+module.exports = {
+ putReview,
+ deleteReview,
+ getReviewParams,
+ getReviews,
+ likeReviewParams,
+ likeReviewQuery,
+ userReviewParams,
+ userReviewQuery,
+ putCommentParams,
+ oeuvreReviewQuery,
+ putCommentPayload,
+ getReviewQuery,
+ oeuvreReviewParams,
+ artistReviewParams,
+ artistReviewQuery,
+};
diff --git a/lib/domain/entity/SpotifyEntity.js b/lib/domain/entity/SpotifyEntity.js
index cab88d2..071f957 100644
--- a/lib/domain/entity/SpotifyEntity.js
+++ b/lib/domain/entity/SpotifyEntity.js
@@ -1,5 +1,6 @@
-const Joi = require('@hapi/joi')
-const trackBody = Joi.object().keys({
+// Verifie le bon format de la query / payload
+const Joi = require('joi')
+const search = Joi.object().keys({
query: Joi
.string()
.min(1)
@@ -7,11 +8,10 @@ const trackBody = Joi.object().keys({
.required(),
spotify_filter: Joi
.string()
- .required()
.max(50)
.required()
.custom((value, helpers) =>{
- const allowedValues = ["track","artist","album"]
+ const allowedValues = ["track","artist","album","user"]
const tabValue = value.split(",")
let correct = true
tabValue.forEach((value) => {
@@ -21,9 +21,48 @@ const trackBody = Joi.object().keys({
})
return correct ? value : helpers.error('any.invalid')
}),
- allow_user: Joi.boolean().required(),
limit: Joi.number().integer().required()
})
+const album = Joi.object().keys({
+ id: Joi
+ .string()
+ .min(1)
+ .required(),
+})
+
+const track = Joi.object().keys({
+ id: Joi
+ .string()
+ .min(1)
+ .required(),
+})
+
+
+const fetchArtist = Joi.object().keys({
+ query: Joi.string().min(1).required(), //correspond au ID Artist
+})
+
+const fetchArtistSongs = Joi.object().keys({
+ id: Joi.string().min(1).required(),
+ filter: Joi
+ .string()
+ .optional()
+ .default("album,single")
+ .custom((value, helpers) =>{
+ const allowedValues = ["album","single","appears_on","compilation"]
+ const tabValue = value.replace(/\s/g, '').split(",") // retire les espaces
+
+ // Renvoie une erreur des qu'un filtre n'est pas valide
+ for (const x of tabValue) {
+ if (!allowedValues.includes(x)) {
+ return helpers.error('any.invalid');
+ }
+ }
+ return tabValue.join(",")
+ }),
+
+ limit: Joi.number().integer().optional().min(1).max(50)
+})
-module.exports = {trackBody}
\ No newline at end of file
+module.exports = {album,search,track,fetchArtist,fetchArtistSongs}
\ No newline at end of file
diff --git a/lib/domain/entity/UserEntity.js b/lib/domain/entity/UserEntity.js
index 56746ae..03763ed 100644
--- a/lib/domain/entity/UserEntity.js
+++ b/lib/domain/entity/UserEntity.js
@@ -1,22 +1,128 @@
-const Joi = require('@hapi/joi')
-const validationErrror = require("./utils/validationError")
+const Joi = require("joi");
+const validationErrror = require("./utils/validationError");
const userSignIn = Joi.object().keys({
- email: Joi.string().max(40).required(),
- password: Joi.string().max(30).required(),
-})
+ email: Joi.string().max(40).required(),
+ password: Joi.string().max(30).required(),
+});
const userSignUp = Joi.object().keys({
- email: Joi.string().email().min(10).max(40).error(validationErrror("email","l'email est invalide")),
- pseudo: Joi.string().min(3).max(15).custom((value, helpers) => {
- if (value.includes('@')) {
- return helpers.error('any.invalid');
- }
- return value;
- }, 'pseudo validation').error(validationErrror("pseudo","le pseudo doit être compris entre 3 et 15 caractère")),
- alias: Joi.string().min(3).max(15).error(validationErrror("alias","l'alias doit être compris entre 3 et 15 caractère")),
- password: Joi.string().min(8).max(30).error(validationErrror("password","le mot de passe doit être compris entre 8 et 30 caractères")),
- spotifyToken: Joi.string().max(40),
- bio:Joi.string().max(1500).error(validationErrror("bio","le pseudo doit faire moins de 1500 caractères")),
-})
+ pseudo: Joi.string()
+ .min(3)
+ .max(15)
+ .required()
+ .custom((value, helpers) => {
+ if (value.includes("@")) {
+ return helpers.error("any.invalid");
+ }
+ return value;
+ }, "pseudo validation")
+ .error(
+ validationErrror(
+ "pseudo",
+ "le pseudo doit être compris entre 3 et 15 caractère"
+ )
+ ),
+ alias: Joi.string()
+ .min(3)
+ .max(15)
+ .error(
+ validationErrror(
+ "alias",
+ "l'alias doit être compris entre 3 et 15 caractère"
+ )
+ ),
+ photo: Joi.string().max(500),
+ confirmToken: Joi.string().max(50),
+ bio: Joi.string()
+ .min(0)
+ .max(1500)
+ .error(
+ validationErrror("bio", "la bio doit faire moins de 1500 caractères")
+ ),
+});
+const uploadPreview = Joi.object().keys({
+ file: Joi.any(),
+});
+const createUser = Joi.object().keys({
+ email: Joi.string().email().min(10).max(40).required(),
+ password: Joi.string().max(30).required(),
+});
+const authWithSpotify = Joi.object().keys({
+ spotify_code: Joi.string().max(1000).required(),
+ callback: Joi.string().max(100).required(),
+});
+const isUser = Joi.object().keys({
+ pseudo: Joi.string().max(15).required(),
+});
+const getUserByConfirmToken = Joi.object().keys({
+ confirmToken: Joi.string().max(50).required(),
+});
+const sendResetEmail = Joi.object().keys({
+ email: Joi.string().email().min(10).max(40),
+});
+const resetPassword = Joi.object().keys({
+ resetToken: Joi.string().max(50).required(),
+ password: Joi.string()
+ .min(8)
+ .max(30)
+ .required()
+ .error(
+ validationErrror(
+ "password",
+ "le mot de passe doit être compris entre 8 et 30 caractères"
+ )
+ ),
+});
+const follow = Joi.object().keys({
+ artistId: Joi.string().min(1).required(),
+});
+const oeuvreFav = Joi.object().keys({
+ idOeuvre: Joi.string().min(1).required(),
+ type: Joi.string()
+ .required()
+ .custom((value, helpers) => {
+ const allowedValues = ["track", "album", "single"];
+ return allowedValues.includes(value)
+ ? value
+ : helpers.error("any.invalid");
+ }),
+});
-module.exports = {userSignIn, userSignUp}
\ No newline at end of file
+const getPageQuery = Joi.object().keys({
+ page: Joi.number().integer().min(1).required(),
+ pageSize: Joi.number().integer().min(1).required(),
+ orderByLike: Joi.boolean(),
+});
+
+const getPageParams = Joi.object().keys({
+ id: Joi.string().min(1).max(50).required(),
+});
+
+const modifyPayload = Joi.object().keys({
+ photo: Joi.any(),
+ bio: Joi.string()
+ .min(0)
+ .max(200)
+ .error(
+ validationErrror("bio", "la bio doit faire moins de 200 caractères")
+ ),
+ pseudo: Joi.string().min(3).max(15),
+ alias: Joi.string().min(3).max(15),
+ isPrivate: Joi.boolean(),
+});
+module.exports = {
+ userSignIn,
+ userSignUp,
+ uploadPreview,
+ createUser,
+ isUser,
+ getUserByConfirmToken,
+ sendResetEmail,
+ resetPassword,
+ follow,
+ authWithSpotify,
+ oeuvreFav,
+ getPageQuery,
+ getPageParams,
+ modifyPayload,
+};
diff --git a/lib/domain/model/Album.js b/lib/domain/model/Album.js
index 3780df8..94ea97a 100644
--- a/lib/domain/model/Album.js
+++ b/lib/domain/model/Album.js
@@ -3,12 +3,17 @@ module.exports = class {
this.id = album.id
this.name = album.name
this.popularity = album.popularity
+ this.rating = album.rating
+ this.reviewCount = album.reviewCount
this.release_date = album.release_date
this.total_tracks = album.total_tracks
- this.images = album.images
+ this.image = album.image
this.spotify_url = album.spotify_url
this.artists = album.artists
+ this.tracks = album.tracks
this.genres = album.genres
- this.type = "album"
+ this.type = album.type
+ this.likeCount = album.likeCount
+
}
}
\ No newline at end of file
diff --git a/lib/domain/model/Artist.js b/lib/domain/model/Artist.js
index c8c3a03..ed67f9f 100644
--- a/lib/domain/model/Artist.js
+++ b/lib/domain/model/Artist.js
@@ -1,10 +1,10 @@
-const {spotify_url} = require("./Track");
module.exports = class {
constructor(artist) {
this.id = artist?.id;
this.name = artist.name;
- this.images = artist?.images;
+ this.image = artist?.image;
this.popularity = artist?.popularity
+ this.follower_count = artist?.follower_count
this.genres = artist?.genres
this.spotify_url = artist?.spotify_url
this.type = "artist"
diff --git a/lib/domain/model/ArtistFollowersPage.js b/lib/domain/model/ArtistFollowersPage.js
new file mode 100644
index 0000000..503d224
--- /dev/null
+++ b/lib/domain/model/ArtistFollowersPage.js
@@ -0,0 +1,6 @@
+module.exports = class {
+ constructor(artist,allFollowers){
+ this.artist = artist
+ this.allFollowers = allFollowers
+ }
+}
\ No newline at end of file
diff --git a/lib/domain/model/ArtistPage.js b/lib/domain/model/ArtistPage.js
new file mode 100644
index 0000000..f8c0445
--- /dev/null
+++ b/lib/domain/model/ArtistPage.js
@@ -0,0 +1,19 @@
+module.exports = class {
+ constructor(
+ artist,
+ albums,
+ friends_followers,
+ reviewsByLike,
+ reviewsByTime,
+ reviewsByFriends,
+ doesUserFollow
+ ) {
+ this.artist = artist;
+ this.albums = albums;
+ this.friends_followers = friends_followers;
+ this.reviewsByLike = reviewsByLike;
+ this.reviewsByTime = reviewsByTime;
+ this.reviewsByFriends = reviewsByFriends;
+ this.doesUserFollow = doesUserFollow;
+ }
+};
diff --git a/lib/domain/model/Comment.js b/lib/domain/model/Comment.js
new file mode 100644
index 0000000..74f2f95
--- /dev/null
+++ b/lib/domain/model/Comment.js
@@ -0,0 +1,12 @@
+module.exports = class {
+ constructor(comment,utilisateur) {
+ this.id_com = comment.id_com
+ this.id_review = comment.id_review
+ this.id_reponse = comment.id_reponse
+ this.description = comment.description
+ this.countLike = comment.countLike
+ this.countComment = comment.countComment
+ this.createdAt = comment.createdAt
+ this.utilisateur = utilisateur
+ }
+}
\ No newline at end of file
diff --git a/lib/domain/model/Friend.js b/lib/domain/model/Friend.js
new file mode 100644
index 0000000..d430343
--- /dev/null
+++ b/lib/domain/model/Friend.js
@@ -0,0 +1,13 @@
+'use strict';
+
+module.exports = class {
+
+ constructor(userRaw) {
+ this.id_utilisateur = userRaw?.id_utilisateur
+ this.amiIdUtilisateur = userRaw?.amiIdUtilisateur
+ this.en_attente = userRaw?.en_attente
+ this.createdAt = userRaw?.createdAt
+ this.updatedAt = userRaw?.updatedAt
+ this.type = 'amis'
+ }
+}
\ No newline at end of file
diff --git a/lib/domain/model/ListsFriendsRequestsPage.js b/lib/domain/model/ListsFriendsRequestsPage.js
new file mode 100644
index 0000000..6b718b4
--- /dev/null
+++ b/lib/domain/model/ListsFriendsRequestsPage.js
@@ -0,0 +1,6 @@
+module.exports = class {
+ constructor(usersPrivateRequestsReceived,usersPrivateRequestsSend){
+ this.requestsReceived = usersPrivateRequestsReceived
+ this.requestsSend = usersPrivateRequestsSend
+ }
+}
\ No newline at end of file
diff --git a/lib/domain/model/OeuvreFav.js b/lib/domain/model/OeuvreFav.js
new file mode 100644
index 0000000..2c8f438
--- /dev/null
+++ b/lib/domain/model/OeuvreFav.js
@@ -0,0 +1,10 @@
+'use strict';
+
+module.exports = class {
+
+ constructor(oeuvreFavRaw) {
+ this.id_oeuvre = oeuvreFavRaw?.id_oeuvre
+ this.id_utilisateur = oeuvreFavRaw?.id_utilisateur
+ this.type = oeuvreFavRaw?.type
+ }
+}
\ No newline at end of file
diff --git a/lib/domain/model/OeuvrePage.js b/lib/domain/model/OeuvrePage.js
new file mode 100644
index 0000000..6c67011
--- /dev/null
+++ b/lib/domain/model/OeuvrePage.js
@@ -0,0 +1,10 @@
+module.exports = class {
+ constructor(oeuvre, artist, reviewsByLike, reviewsByTime, doesUserLikes, doesUserFav){
+ this.oeuvre = oeuvre
+ this.artist = artist
+ this.reviewsByLike = reviewsByLike
+ this.reviewsByTime = reviewsByTime
+ this.doesUserLikes = doesUserLikes
+ this.doesUserFav = doesUserFav
+ }
+}
\ No newline at end of file
diff --git a/lib/domain/model/PublicComment.js b/lib/domain/model/PublicComment.js
new file mode 100644
index 0000000..d1eb4bc
--- /dev/null
+++ b/lib/domain/model/PublicComment.js
@@ -0,0 +1,11 @@
+module.exports = class {
+ constructor(comment,utilisateur) {
+ this.id_com = comment.id_com
+ this.countLike = comment.countLike
+ this.countComment = comment.countComment
+ this.description = comment.description
+ this.doesUserLike = !!comment.doesUserLike
+ this.createdAt = comment.createdAt
+ this.utilisateur = utilisateur
+ }
+}
\ No newline at end of file
diff --git a/lib/domain/model/Review.js b/lib/domain/model/Review.js
new file mode 100644
index 0000000..a856510
--- /dev/null
+++ b/lib/domain/model/Review.js
@@ -0,0 +1,15 @@
+module.exports = class {
+ constructor(rawReview, utilisateur,type) {
+ this.id_review = rawReview.id_review
+ this.id_oeuvre = rawReview.id_oeuvre
+ this.countlike = rawReview.dataValues.countLike
+ this.countComment = rawReview.dataValues.countComment
+ this.description = rawReview.description
+ this.note = rawReview.note
+ this.createdAt = rawReview.createdAt
+ this.updated_at = rawReview.updatedAt
+ this.type = type
+
+ this.utilisateur = utilisateur
+ }
+}
\ No newline at end of file
diff --git a/lib/domain/model/ReviewPublic.js b/lib/domain/model/ReviewPublic.js
new file mode 100644
index 0000000..9fda81d
--- /dev/null
+++ b/lib/domain/model/ReviewPublic.js
@@ -0,0 +1,16 @@
+module.exports = class {
+ constructor(rawReview, oeuvre, utilisateur, doesUserLike, comments) {
+ this.id_review = rawReview.id_review;
+ this.description = rawReview.description;
+ this.countlike = rawReview.countlike;
+ this.countComment = rawReview.countComment;
+ this.doesUserLike = doesUserLike;
+ this.note = rawReview.note;
+ this.createdAt = rawReview.createdAt;
+ this.oeuvre = oeuvre;
+ this.utilisateur = utilisateur;
+ this.comments = comments;
+ this.made_by_friend = rawReview.made_by_friend;
+ this.type = rawReview.type;
+ }
+};
diff --git a/lib/domain/model/Track.js b/lib/domain/model/Track.js
index 4cecd66..722833b 100644
--- a/lib/domain/model/Track.js
+++ b/lib/domain/model/Track.js
@@ -1,12 +1,17 @@
module.exports = class {
- constructor(track) {
- this.id = track.id
- this.name = track.name
- this.album = track.album
- this.artists = track.artists
- this.duration_ms = track.duration_ms
- this.popularity = track.popularity
- this.spotify_url = track.spotify_url
- this.type = "track"
- }
-}
\ No newline at end of file
+ constructor(track) {
+ this.id = track.id;
+ this.name = track.name;
+ this.album = track.album;
+ this.artists = track.artists;
+ this.duration_ms = track.duration_ms;
+ this.popularity = track.popularity;
+ this.spotify_url = track.spotify_url;
+ this.rating = track.rating;
+ this.reviewCount = track.reviewCount;
+ this.likeCount = track.likeCount;
+ this.release_date = track.release_date;
+ this.image = track.album?.image;
+ this.type = "track";
+ }
+};
diff --git a/lib/domain/model/User.js b/lib/domain/model/User.js
index d5c2153..b21948c 100644
--- a/lib/domain/model/User.js
+++ b/lib/domain/model/User.js
@@ -2,17 +2,28 @@
module.exports = class {
- constructor(id = null, pseudo, email,alias, bio, password,spotifyToken,id_role, id_etat) {
- this.id = id;
- this.pseudo = pseudo;
- this.email = email;
- this.alias = alias
- this.bio = bio
- this.spotifyToken = spotifyToken
- this.password = password;
- this.id_role = id_role;
- this.id_etat = id_etat
- this.type = 'user'
+ constructor(userRaw) {
+ this.id_utilisateur = userRaw?.id_utilisateur
+ this.pseudo = userRaw?.pseudo
+ this.bio = userRaw?.bio
+ this.email = userRaw?.email
+ this.alias = userRaw?.alias
+ this.following_count = userRaw?.following_count
+ this.follower_count = userRaw?.follower_count
+ this.review_count = userRaw?.review_count
+ this.photo = userRaw?.photo
+ this.photo_temporaire = userRaw?.photo_temporaire
+ this.token = userRaw?.token
+ this.refresh_token = userRaw?.refresh_token
+ this.reset_token = userRaw?.reset_token
+ this.password = userRaw?.password;
+ this.id_role = userRaw?.id_role;
+ this.ban_until = userRaw?.ban_until
+ this.confirmed= userRaw?.confirmed
+ this.confirm_token = userRaw?.confirm_token
+ this.auth_with_spotify = userRaw?.auth_with_spotify
+ this.is_private = userRaw?.is_private
+ this.type = 'user'
}
};
\ No newline at end of file
diff --git a/lib/domain/model/UserPublic.js b/lib/domain/model/UserPublic.js
new file mode 100644
index 0000000..796d81b
--- /dev/null
+++ b/lib/domain/model/UserPublic.js
@@ -0,0 +1,29 @@
+"use strict";
+const formatPhoto = (photo) => {
+ if (
+ !photo ||
+ "https://" === photo.substring(0, 8) ||
+ "http://" === photo.substring(0, 7)
+ )
+ return photo;
+ return `${process.env.API_URL}/${photo}`;
+};
+module.exports = class {
+ constructor(userRaw) {
+ this.id_utilisateur = userRaw?.id_utilisateur;
+ this.pseudo = userRaw?.pseudo;
+ this.email = userRaw?.email;
+ this.alias = userRaw?.alias;
+ this.photo = formatPhoto(userRaw?.photo);
+ this.bio = userRaw?.bio;
+ this.following_count = userRaw?.following_count;
+ this.follower_count = userRaw?.follower_count;
+ this.review_count = userRaw?.review_count;
+ this.photo_temporaire = formatPhoto(userRaw?.photo_temporaire);
+ this.id_role = userRaw?.id_role;
+ this.ban_until = userRaw?.ban_until;
+ this.is_private = userRaw?.is_private;
+ this.auth_with_spotify = userRaw?.auth_with_spotify;
+ this.type = "user";
+ }
+};
diff --git a/lib/domain/model/utils/EtatsEnum.js b/lib/domain/model/utils/EtatsEnum.js
deleted file mode 100644
index 20f5d9c..0000000
--- a/lib/domain/model/utils/EtatsEnum.js
+++ /dev/null
@@ -1,4 +0,0 @@
-module.exports = {
- LIBRE : 1,
- BAN : 2,
-}
\ No newline at end of file
diff --git a/lib/infrastructure/config/service-locator.js b/lib/infrastructure/config/service-locator.js
index de5db8a..ff71ea1 100644
--- a/lib/infrastructure/config/service-locator.js
+++ b/lib/infrastructure/config/service-locator.js
@@ -1,16 +1,31 @@
'use strict';
-const constants = require('./constants');
-const environment = require('./environment');
+
const UserRepository= require('../repositories/UserRepository');
const spotifyRepository= require('../repositories/SpotifyRepository');
const JwtAccessTokenManager = require('../security/JwtAccessTokenManager');
+const documentRepository= require('../repositories/DocumentRepository');
+const NodemailerRepository= require('../repositories/NodemailerRepository');
+const FollowRepository= require('../repositories/FollowRepository');
+const FriendRepository= require('../repositories/FriendRepository');
+const ReviewRepository= require('../repositories/ReviewRepository');
+const LikeOeuvreRepository= require('../repositories/LikeOeuvreRepository');
+const CommentRepository= require('../repositories/CommentRepository');
+const OeuvreFavRepository= require('../repositories/OeuvreFavRepository');
function buildBeans() {
return {
accessTokenManager: new JwtAccessTokenManager(),
userRepository: new UserRepository(),
spotifyRepository: new spotifyRepository(process.env.CLIENT_ID,process.env.CLIENT_SECRET),
+ documentRepository: new documentRepository(),
+ mailRepository: new NodemailerRepository(process.env.MAILER_SERVICE,process.env.MAILER_EMAIL,process.env.MAILER_PASS),
+ followRepository: new FollowRepository(),
+ friendRepository: new FriendRepository(),
+ oeuvreFavRepository: new OeuvreFavRepository(),
+ reviewRepository: new ReviewRepository(),
+ likeOeuvreRepository: new LikeOeuvreRepository(),
+ commentRepository: new CommentRepository()
};
}
diff --git a/lib/infrastructure/config/strategy.js b/lib/infrastructure/config/strategy.js
new file mode 100644
index 0000000..ea0ea4d
--- /dev/null
+++ b/lib/infrastructure/config/strategy.js
@@ -0,0 +1,18 @@
+module.exports = ({userRepository}) =>{
+ return {
+ keys: process.env.SECRET_ENCODER, // replace with your secret key for signing and verifying JWTs
+ verify: {
+ aud: 'urn:audience:test',
+ iss: 'urn:issuer:test',
+ sub: false,
+ nbf: true,
+ timeSkewSec: 15
+ },
+ validate: async (artifacts, request, h) => {
+ const isValid = !!await userRepository.getByUser(artifacts.decoded.payload.value)
+ return {
+ isValid,
+ };
+ },
+ }
+}
\ No newline at end of file
diff --git a/lib/infrastructure/orm/sequelize/models/Amis.js b/lib/infrastructure/orm/sequelize/models/Amis.js
index 6a380e7..584d1b6 100644
--- a/lib/infrastructure/orm/sequelize/models/Amis.js
+++ b/lib/infrastructure/orm/sequelize/models/Amis.js
@@ -2,13 +2,11 @@ const { DataTypes } = require('sequelize');
module.exports = (sequelize) => {
return sequelize.define('amis', {
-
- // attributes
en_attente: {
type: DataTypes.BOOLEAN,
allowNull: false,
},
},
- { freezeTableName: true,});
+ { freezeTableName: true,});
};
diff --git a/lib/infrastructure/orm/sequelize/models/Commentaire.js b/lib/infrastructure/orm/sequelize/models/Commentaire.js
index 7c5b24e..2b74d08 100644
--- a/lib/infrastructure/orm/sequelize/models/Commentaire.js
+++ b/lib/infrastructure/orm/sequelize/models/Commentaire.js
@@ -13,6 +13,10 @@ module.exports = (sequelize) => {
type: DataTypes.STRING(1500),
allowNull: false,
},
+ deleted: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ }
},
{ freezeTableName: true,});
diff --git a/lib/infrastructure/orm/sequelize/models/Etat.js b/lib/infrastructure/orm/sequelize/models/Etat.js
deleted file mode 100644
index 0241add..0000000
--- a/lib/infrastructure/orm/sequelize/models/Etat.js
+++ /dev/null
@@ -1,19 +0,0 @@
-const { DataTypes } = require('sequelize');
-module.exports = (sequelize) => {
-
- return sequelize.define('etat', {
-
- // attributes
- id_etat: {
- type: DataTypes.INTEGER,
- primaryKey: true,
- autoIncrement: true,
- },
- libelle: {
- type: DataTypes.STRING(20),
- allowNull: false,
- },
- },
- { freezeTableName: true,});
-
-};
diff --git a/lib/infrastructure/orm/sequelize/models/OeuvreFavorite.js b/lib/infrastructure/orm/sequelize/models/OeuvreFavorite.js
index 50cfde8..7d4f8dd 100644
--- a/lib/infrastructure/orm/sequelize/models/OeuvreFavorite.js
+++ b/lib/infrastructure/orm/sequelize/models/OeuvreFavorite.js
@@ -17,7 +17,11 @@ module.exports = (sequelize) => {
model: 'utilisateur',
key: 'id_utilisateur',
},
- }
+ },
+ type: {
+ type: DataTypes.STRING(50),
+ allowNull: false,
+ },
},
{ freezeTableName: true,});
diff --git a/lib/infrastructure/orm/sequelize/models/Review.js b/lib/infrastructure/orm/sequelize/models/Review.js
index 8d9a18d..b101ca3 100644
--- a/lib/infrastructure/orm/sequelize/models/Review.js
+++ b/lib/infrastructure/orm/sequelize/models/Review.js
@@ -19,6 +19,10 @@ module.exports = (sequelize) => {
note: {
type: DataTypes.INTEGER,
},
+ deleted: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ }
},
{ freezeTableName: true,});
diff --git a/lib/infrastructure/orm/sequelize/models/TypeReview.js b/lib/infrastructure/orm/sequelize/models/TypeReview.js
index ff3e1ba..00e8285 100644
--- a/lib/infrastructure/orm/sequelize/models/TypeReview.js
+++ b/lib/infrastructure/orm/sequelize/models/TypeReview.js
@@ -4,7 +4,7 @@ module.exports = (sequelize) => {
return sequelize.define('type_review', {
// attributes
- id_type_teview: {
+ id_type_review: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
diff --git a/lib/infrastructure/orm/sequelize/models/Utilisateur.js b/lib/infrastructure/orm/sequelize/models/Utilisateur.js
index 84fac16..92143ab 100644
--- a/lib/infrastructure/orm/sequelize/models/Utilisateur.js
+++ b/lib/infrastructure/orm/sequelize/models/Utilisateur.js
@@ -12,37 +12,61 @@ module.exports = (sequelize) => {
},
pseudo: {
type: DataTypes.STRING(15),
- allowNull: false,
unique: true,
},
alias: {
type: DataTypes.STRING(15),
- allowNull: false,
},
password: {
type: DataTypes.STRING(200 ),
- allowNull: false,
},
email: {
type: DataTypes.STRING(30),
unique: true,
allowNull: false,
},
- token_spotify: {
- type: DataTypes.STRING(50),
+ token: {
+ type: DataTypes.STRING(400),
unique: true,
},
+ refresh_token: {
+ type: DataTypes.STRING(400),
+ unique: true,
+ },
+ auth_with_spotify: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
id_spotify: {
type: DataTypes.STRING(50),
},
photo: {
type: DataTypes.STRING(250),
},
+ photo_temporaire: {
+ type: DataTypes.STRING(250),
+ },
+ ban_until: {
+ type: DataTypes.DATE
+ },
bio: {
type: DataTypes.STRING(1500),
},
+ confirmed: {
+ type: DataTypes.BOOLEAN
+ },
+ confirm_token: {
+ type: DataTypes.STRING(50),
+ },
+ reset_token: {
+ type: DataTypes.STRING(50),
+ },
+ is_private : {
+ type: DataTypes.BOOLEAN,
+ defaultValue: false
+ },
},
- { freezeTableName: true,}
+ { freezeTableName: true,}
);
};
diff --git a/lib/infrastructure/orm/sequelize/sequelize.js b/lib/infrastructure/orm/sequelize/sequelize.js
index 35a6951..8268c61 100644
--- a/lib/infrastructure/orm/sequelize/sequelize.js
+++ b/lib/infrastructure/orm/sequelize/sequelize.js
@@ -1,131 +1,121 @@
-'use strict';
-const { Sequelize } = require('sequelize');
-const environment = require('../../config/environment');
+"use strict";
+const { Sequelize } = require("sequelize");
+const environment = require("../../config/environment");
const sequelize = new Sequelize(environment.database.url);
-const UserModel = require('./models/Utilisateur')(sequelize)
-const RoleModel = require('./models/Role')(sequelize)
-const AmisModel = require('./models/Amis')(sequelize)
-const ArtisteModel = require('./models/Artiste')(sequelize)
-const ReviewModel = require('./models/Review')(sequelize)
-const TypeReviewModel = require('./models/TypeReview')(sequelize)
-const CommentaireModel = require('./models/Commentaire')(sequelize)
-const EtatModel = require('./models/Etat')(sequelize)
-
-require('./models/LikeOeuvre')(sequelize)
-require('./models/OeuvreFavorite')(sequelize)
-
-
+const UserModel = require("./models/Utilisateur")(sequelize);
+const RoleModel = require("./models/Role")(sequelize);
+const AmisModel = require("./models/Amis")(sequelize);
+const ArtisteModel = require("./models/Artiste")(sequelize);
+const ReviewModel = require("./models/Review")(sequelize);
+const TypeReviewModel = require("./models/TypeReview")(sequelize);
+const CommentaireModel = require("./models/Commentaire")(sequelize);
+require("./models/LikeOeuvre")(sequelize);
+require("./models/OeuvreFavorite")(sequelize);
//un utilisateur a un role
-UserModel.belongsTo(RoleModel,
- {foreignKey: 'id_role'})
+UserModel.belongsTo(RoleModel, { foreignKey: "id_role" });
//un utilisateur a un etat
-UserModel.belongsTo(EtatModel,
- {foreignKey: 'id_etat'})
-
-//un utilisateur peut avoir plusieurs amis
-UserModel.belongsToMany(UserModel,
- {
- as: 'amis_1',
- foreignKey: 'amis_1_id',
- through : AmisModel
- }
-)
-UserModel.belongsToMany(UserModel,
- {
- as: 'amis_2',
- foreignKey: 'amis_2_id',
- through : AmisModel
- }
-)
-
-UserModel.belongsToMany(CommentaireModel,
- {
- as: 'user_like_comment',
- foreignKey: 'id_user',
- through : 'like_commentaire'
- }
-)
-
-CommentaireModel.belongsToMany(UserModel,
- {
- as: 'comment_like',
- foreignKey: 'id_com',
- through : 'like_commentaire'
- }
-)
-UserModel.belongsToMany(ArtisteModel,
- {
- as: 'utilisateur',
- foreignKey: 'id_utilisateur',
- through : 'follow'
- }
-)
-ArtisteModel.belongsToMany(UserModel,
- {
- as: 'artiste',
- foreignKey: 'id_artiste',
- through : 'follow'
- }
-)
-UserModel.belongsToMany(ReviewModel,{
- as: 'user_like_review',
- foreignKey: 'id_artiste',
- through : 'like_review'
-})
-ReviewModel.belongsToMany(UserModel,{
- as: 'review_like',
- foreignKey: 'id_review',
- through : 'like_review'
-})
+UserModel.belongsToMany(UserModel, {
+ as: "ami",
+ foreignKey: {
+ name: "id_utilisateur",
+ primaryKey: true,
+ },
+ through: {
+ model: AmisModel,
+ primaryKey: true,
+ },
+});
+
+UserModel.belongsToMany(CommentaireModel, {
+ as: "user_like_comment",
+ foreignKey: "id_utilisateur",
+ through: "like_commentaire",
+});
+
+CommentaireModel.belongsToMany(UserModel, {
+ as: "comment_like",
+ foreignKey: "id_com",
+ through: "like_commentaire",
+});
+
+UserModel.belongsToMany(ArtisteModel, {
+ as: "utilisateur_m_n",
+ foreignKey: "id_utilisateur",
+ through: "follow",
+});
+ArtisteModel.belongsToMany(UserModel, {
+ as: "artiste",
+ foreignKey: "id_artiste",
+ through: "follow",
+});
+UserModel.belongsToMany(ReviewModel, {
+ as: "user_like_review",
+ foreignKey: "id_utilisateur",
+ through: "like_review",
+});
+ReviewModel.belongsToMany(UserModel, {
+ as: "review_like",
+ foreignKey: "id_review",
+ through: "like_review",
+});
ReviewModel.belongsTo(UserModel, {
- as:'utilisateur',
- foreignKey:'id_utilisateur'
-})
-
+ as: "utilisateur",
+ foreignKey: "id_utilisateur",
+});
ReviewModel.belongsTo(TypeReviewModel, {
- as:'type_review',
- foreignKey:'id_type_review'
-})
-
+ as: "type_review",
+ foreignKey: "id_type_review",
+});
ReviewModel.hasMany(CommentaireModel, {
- as:'comment_review',
- foreignKey:'id_review'
-})
-CommentaireModel.belongsTo(ReviewModel,{
- as:'review_comment',
- foreignKey:'id_review'
-})
-
-CommentaireModel.hasMany(CommentaireModel,{ as: 'reponse', foreignKey: 'id_reponse' })
-
+ as: "comment_review",
+ foreignKey: "id_review",
+ onDelete: "cascade",
+});
+CommentaireModel.belongsTo(ReviewModel, {
+ as: "review_comment",
+ foreignKey: "id_review",
+});
+
+CommentaireModel.belongsTo(UserModel, {
+ as: "user_review",
+ foreignKey: "id_utilisateur",
+});
+CommentaireModel.hasMany(CommentaireModel, {
+ as: "reponse",
+ foreignKey: "id_reponse",
+ onDelete: "cascade",
+});
RoleModel.sync()
- .then(()=>{
+ .then(() => {
return RoleModel.bulkCreate([
- {id_role: 1, libelle : 'administrateur'},
- {id_role: 2, libelle : 'utlisateur'},
- ])
- })
- .then(() => console.log('Creation des roles réussi'))
- .catch((error) => {
- console.error('Erreur dans la création des roles : '+error)
- })
-
-EtatModel.sync()
- .then(()=>{
- return EtatModel.bulkCreate([
- {id_etat: 1, libelle : 'libre'},
- {id_etat: 2, libelle : 'ban'},
- ])
- })
- .then(() => console.log('Creation des etats réussi'))
- .catch((error) => {
- console.error('Erreur dans la création des etats : '+error)
- })
-module.exports = sequelize;
\ No newline at end of file
+ { id_role: 1, libelle: "administrateur" },
+ { id_role: 2, libelle: "utlisateur" },
+ ]);
+ })
+ .then(() => console.log("Creation des roles réussi"))
+ .catch((error) => {
+ console.error("Erreur dans la création des roles : " + error);
+ });
+
+TypeReviewModel.sync()
+ .then(() => {
+ return TypeReviewModel.bulkCreate([
+ { id_type_review: 1, libelle: "track" },
+ { id_type_review: 2, libelle: "album" },
+ { id_type_review: 3, libelle: "artist" },
+ { id_type_review: 4, libelle: "single" },
+ { id_type_review: 5, libelle: "compilation" },
+ ]);
+ })
+ .then(() => console.log("Creation des types de reviews réussi"))
+ .catch((error) => {
+ console.error("Erreur dans la création des types de reviews : " + error);
+ });
+module.exports = sequelize;
diff --git a/lib/infrastructure/repositories/CommentRepository.js b/lib/infrastructure/repositories/CommentRepository.js
new file mode 100644
index 0000000..aab2798
--- /dev/null
+++ b/lib/infrastructure/repositories/CommentRepository.js
@@ -0,0 +1,253 @@
+"use strict";
+const { Op } = require("sequelize");
+const sequelize = require("../orm/sequelize/sequelize");
+const CommentRepository = require("./interfaces/CommentRepositoryAbstract");
+const Comment = require("../../domain/model/Comment");
+const Utilisateur = require("../../domain/model/UserPublic");
+module.exports = class extends CommentRepository {
+ constructor() {
+ super();
+ this.db = sequelize;
+ this.comment = this.db.model("commentaire");
+ this.user = this.db.model("utilisateur");
+ this.likeCommentaire = this.db.model("like_commentaire");
+ }
+
+ createComment(commentRaw) {
+ return new Comment(commentRaw, new Utilisateur(commentRaw.user_review));
+ }
+ async persist(id_review, description, id_utilisateur, id_reponse = null) {
+ const seqComment = await this.comment.create({
+ id_review,
+ description,
+ id_utilisateur,
+ id_reponse,
+ });
+ return await this.getById(seqComment.id_com);
+ }
+
+ async getCommentsComments(
+ id_reponse,
+ id_utilisateur,
+ fetchPrivate,
+ page,
+ pageSize,
+ orderByLike
+ ) {
+ let whereClause = {
+ id_reponse,
+ deleted: false,
+ };
+ const orderColumn = orderByLike ? "countLike" : "createdAt";
+ const order = [[sequelize.literal(orderColumn), "DESC"]];
+ const offset = (page - 1) * pageSize;
+ if (!fetchPrivate) {
+ whereClause.id_utilisateur = id_utilisateur
+ ? {
+ [Op.in]: sequelize.literal(
+ `(SELECT id_utilisateur FROM utilisateur WHERE is_private = false OR id_utilisateur=${id} OR id_utilisateur IN (SELECT id_utilisateur FROM amis WHERE amiIdUtilisateur = ${id} and en_attente = false) OR id_utilisateur IN (SELECT amiIdUtilisateur FROM amis WHERE id_utilisateur = ${id} and en_attente = false))`
+ ),
+ }
+ : {
+ [Op.in]: sequelize.literal(
+ `(SELECT id_utilisateur FROM utilisateur WHERE is_private = false`
+ ),
+ };
+ }
+ const comments = await this.comment.findAll({
+ offset: offset,
+ attributes: {
+ include: [
+ [
+ sequelize.literal(
+ "(SELECT COUNT(*) FROM like_commentaire WHERE like_commentaire.id_com = commentaire.id_com and deleted=false)"
+ ),
+ "countLike",
+ ],
+ [
+ sequelize.literal(
+ "(SELECT COUNT(*) FROM commentaire AS comm2 WHERE comm2.id_reponse = commentaire.id_com and deleted = false)"
+ ),
+ "countComment",
+ ],
+ ],
+ },
+ include: [
+ {
+ model: this.user,
+ as: "user_review",
+ },
+ // {
+ // model: this.review,
+ // include: [
+ // {
+ // model: this.user,
+ // as: "utilisateur",
+ // }
+ // ],
+ // }
+ ],
+ where: whereClause,
+ order,
+ limit: pageSize,
+ });
+ return comments.map((comment) => this.createComment(comment.dataValues));
+ }
+ async delete(id_com, id_utilisateur) {
+ const seqComment = await this.comment.findOne({
+ where: {
+ id_com,
+ id_utilisateur,
+ },
+ });
+ if (!seqComment) return false;
+ seqComment.deleted = true;
+ await seqComment.save();
+ return true;
+ }
+
+ async getById(id_com, deleted = false) {
+ const comment = await this.comment.findOne({
+ attributes: {
+ include: [
+ [
+ sequelize.literal(
+ "(SELECT COUNT(*) FROM like_commentaire WHERE like_commentaire.id_com = commentaire.id_com and deleted=false)"
+ ),
+ "countLike",
+ ],
+ [
+ sequelize.literal(
+ "(SELECT COUNT(*) FROM commentaire AS comm2 WHERE comm2.id_reponse = commentaire.id_com and deleted = false)"
+ ),
+ "countComment",
+ ],
+ ],
+ },
+ include: [
+ {
+ model: this.user,
+ as: "user_review",
+ },
+ // {
+ // model: this.review,
+ // include: [
+ // {
+ // model: this.user,
+ // as: "utilisateur",
+ // }
+ // ],
+ // }
+ ],
+ where: {
+ id_com,
+ deleted,
+ },
+ });
+ return comment ? this.createComment(comment.dataValues) : null;
+ }
+
+ async doesUserLike(id_com, id_utilisateur) {
+ const count = await this.likeCommentaire.count({
+ where: {
+ id_utilisateur,
+ id_com,
+ },
+ });
+ return count > 0;
+ }
+ async like(id_com, id_utilisateur) {
+ const seqLike = await this.likeCommentaire.create({
+ id_com,
+ id_utilisateur,
+ });
+ await seqLike.save();
+ }
+ unlike(id_com, id_utilisateur) {
+ this.likeCommentaire.destroy({
+ where: {
+ id_utilisateur,
+ id_com,
+ },
+ });
+ }
+
+ async getReviewComments(
+ id_review,
+ id_utilisateur,
+ fetchPrivate,
+ page,
+ pageSize,
+ orderByLike
+ ) {
+ let whereClause = {
+ id_review,
+ id_reponse: null,
+ deleted: false,
+ };
+ const orderColumn = orderByLike ? "countLike" : "createdAt";
+ const order = [[sequelize.literal(orderColumn), "DESC"]];
+ const offset = (page - 1) * pageSize;
+ if (!fetchPrivate) {
+ whereClause.id_utilisateur = id_utilisateur
+ ? {
+ [Op.in]: sequelize.literal(
+ `(SELECT id_utilisateur FROM utilisateur WHERE is_private = false OR id_utilisateur=${id_utilisateur} OR id_utilisateur IN (SELECT id_utilisateur FROM amis WHERE amiIdUtilisateur = ${id_utilisateur} and en_attente = false) OR id_utilisateur IN (SELECT amiIdUtilisateur FROM amis WHERE id_utilisateur = ${id_utilisateur} and en_attente = false))`
+ ),
+ }
+ : {
+ [Op.in]: sequelize.literal(
+ `(SELECT id_utilisateur FROM utilisateur WHERE is_private = false`
+ ),
+ };
+ }
+
+ const comments = await this.comment.findAll({
+ offset: offset,
+ attributes: {
+ include: [
+ [
+ sequelize.literal(
+ "(SELECT COUNT(*) FROM like_commentaire WHERE like_commentaire.id_com = commentaire.id_com and deleted=false)"
+ ),
+ "countLike",
+ ],
+ [
+ sequelize.literal(
+ "(SELECT COUNT(*) FROM commentaire AS comm2 WHERE comm2.id_reponse = commentaire.id_com and deleted = false)"
+ ),
+ "countComment",
+ ],
+ ],
+ },
+ include: [
+ {
+ model: this.user,
+ as: "user_review",
+ },
+ // {
+ // model: this.review,
+ // include: [
+ // {
+ // model: this.user,
+ // as: "utilisateur",
+ // }
+ // ],
+ // }
+ ],
+ where: whereClause,
+ order,
+ limit: pageSize,
+ });
+ return comments.map((comment) => this.createComment(comment.dataValues));
+ }
+ async canDelete(id_com, id_utilisateur) {
+ const count = await this.comment.count({
+ where: {
+ id_com,
+ id_utilisateur,
+ },
+ });
+ return count !== 0;
+ }
+};
diff --git a/lib/infrastructure/repositories/DocumentRepository.js b/lib/infrastructure/repositories/DocumentRepository.js
new file mode 100644
index 0000000..ae1b953
--- /dev/null
+++ b/lib/infrastructure/repositories/DocumentRepository.js
@@ -0,0 +1,33 @@
+'use strict';
+const documentRepositoryAbstract = require('./interfaces/DoucumentRepositoryAbstract')
+const {unlink, writeFile} = require("fs");
+const crypto = require("crypto");
+
+module.exports = class extends documentRepositoryAbstract{
+
+ uploadFile(folderPath,file) {
+ return new Promise((resolve, reject) => {
+ const fileLabel = crypto.randomBytes(16).toString('hex')
+ const fileExt = file.hapi.filename.split(".")[1]
+ const path = `${folderPath}/${fileLabel}.${fileExt}`
+ writeFile(`./${path}`, file._data, err => {
+ if (err) {
+ reject(err)
+ }
+ resolve(path)
+ })
+ })
+ }
+ deleteFile(path){
+ unlink(`./${path}`,err => {
+ if(err){
+ throw err
+ }
+ })
+ }
+
+
+
+
+
+};
diff --git a/lib/infrastructure/repositories/FollowRepository.js b/lib/infrastructure/repositories/FollowRepository.js
new file mode 100644
index 0000000..cfcbf85
--- /dev/null
+++ b/lib/infrastructure/repositories/FollowRepository.js
@@ -0,0 +1,156 @@
+'use strict';
+
+const sequelize = require('../orm/sequelize/sequelize');
+const FollowRepository = require('./interfaces/FollowRepositoryAbstract');
+const User = require("../../domain/model/User");
+const {Op} = require('sequelize');
+
+module.exports = class extends FollowRepository {
+
+ constructor() {
+ super();
+ this.db = sequelize;
+ this.followModel = this.db.model('follow');
+ this.artistModel = this.db.model('artiste');
+ this.userModel = this.db.model('utilisateur');
+ }
+
+ async follow(userId, artistId) {
+ let artist = await this.artistModel.findOne({
+ where: {
+ id_artiste: artistId
+ }
+ })
+ if(!artist){
+ artist = await this.artistModel.create({
+ id_artiste: artistId,
+ nb_suivis: 0
+ })
+ }
+ artist.nb_suivis = artist.nb_suivis < 0 ? 0 : artist.nb_suivis
+ artist.save()
+ const follow = await this.followModel.create({
+ id_utilisateur: userId,
+ id_artiste: artistId
+ });
+ artist.nb_suivis += 1
+ artist.save()
+ await follow.save();
+ }
+
+ async unfollow(userId, artistId) {
+ const artist = await this.artistModel.findOne({
+ where: {
+ id_artiste: artistId
+ }
+ })
+ await this.followModel.destroy({
+ where: {
+ id_utilisateur: userId,
+ id_artiste: artistId
+ }
+ })
+ artist.nb_suivis -= 1
+ artist.save()
+ }
+ async doesFollows(userId, artistId) {
+ const follow = await this.followModel.findOne({
+ where: {
+ id_utilisateur: userId,
+ id_artiste: artistId
+ }
+ })
+ return !!follow
+ }
+
+ async getFollowersCount(idArtist) {
+ const artist = await this.artistModel.findOne({
+ where: {
+ id_artiste: idArtist
+ }
+ })
+ return artist?.nb_suivis || 0
+ }
+
+ async getFriendsFollowing(idArtist,idUser,limit) {
+ const users = await this.userModel.findAll({
+ limit,
+ include: [
+ {
+ model: this.artistModel,
+ as: 'utilisateur_m_n',
+ required: true,
+ through: {
+ where: {
+ id_artiste: idArtist
+ }
+ }
+ }
+ ],
+ where: {
+
+ [Op.or]: [
+ sequelize.literal(` utilisateur.id_utilisateur IN (SELECT amiIdUtilisateur FROM amis WHERE id_utilisateur = ${idUser} AND en_attente = false )`),
+ sequelize.literal(`utilisateur.id_utilisateur IN (SELECT id_utilisateur FROM amis WHERE amiIdUtilisateur = ${idUser} AND en_attente = false )`)
+ ]
+
+ }
+ })
+
+ return users.map(item => new User(item))
+ }
+ async getFriendsFollowingCount(idArtist,idUser) {
+ const countUsers = await this.userModel.count({
+ include: [
+ {
+ model: this.artistModel,
+ as: 'utilisateur_m_n',
+ required: true,
+ through: {
+ where: {
+ id_artiste: idArtist
+ }
+ }
+ }
+ ],
+ where: {
+ //id_utilisateur: {[Op.in]: sequelize.literal(`(SELECT id_utilisateur FROM utilisateur WHERE id_utilisateur IN (SELECT id_utilisateur FROM amis WHERE amiIdUtilisateur = :idUser))`)}
+ [Op.or]: [
+ sequelize.literal(` utilisateur.id_utilisateur IN (SELECT amiIdUtilisateur FROM amis WHERE id_utilisateur = ${idUser} AND en_attente = false )`),
+ sequelize.literal(`utilisateur.id_utilisateur IN (SELECT id_utilisateur FROM amis WHERE amiIdUtilisateur = ${idUser} AND en_attente = false )`)
+ ]
+ },
+ replacements: { idUser },
+ })
+ return countUsers
+ }
+ async getArtistFollowersWithoutFriends(idArtist,idUser,limit) {
+ //affiche idUser s'il follow l'artiste
+ const users = await this.userModel.findAll({
+ limit,
+ include: [
+ {
+ model: this.artistModel,
+ as: 'utilisateur_m_n',
+ required: true,
+ through: {
+ where: {
+ id_artiste: idArtist
+ }
+ }
+ }
+ ],
+ where: {
+ //id_utilisateur: {[Op.notIn]: sequelize.literal(`(SELECT id_utilisateur FROM utilisateur WHERE id_utilisateur IN (SELECT id_utilisateur FROM amis WHERE amiIdUtilisateur = ${idUser}))`)}
+ [Op.and]: [
+ sequelize.literal(`utilisateur.id_utilisateur not IN (SELECT id_utilisateur FROM amis WHERE amiIdUtilisateur = ${idUser} AND en_attente = false)`),
+ sequelize.literal(`utilisateur.id_utilisateur not IN (SELECT amiIdUtilisateur FROM amis WHERE id_utilisateur = ${idUser} AND en_attente = false)`),
+
+ ]
+ }
+ })
+
+ return users.map(item => new User(item))
+ }
+};
+
diff --git a/lib/infrastructure/repositories/FriendRepository.js b/lib/infrastructure/repositories/FriendRepository.js
new file mode 100644
index 0000000..05fc0bf
--- /dev/null
+++ b/lib/infrastructure/repositories/FriendRepository.js
@@ -0,0 +1,189 @@
+"use strict";
+
+const sequelize = require("../orm/sequelize/sequelize");
+const Friend = require("../../domain/model/Friend");
+const User = require("../../domain/model/User");
+const FriendRepositoryAbstract = require("./interfaces/FriendRepositoryAbstract");
+const { Op } = require("sequelize");
+
+module.exports = class extends FriendRepositoryAbstract {
+ constructor() {
+ super();
+ this.db = sequelize;
+ this.model = this.db.model("amis");
+ this.UserModel = this.db.model("utilisateur");
+ }
+
+ async persist(friendEntity) {
+ friendEntity.createdAt = sequelize.literal("CURRENT_TIMESTAMP");
+ friendEntity.updatedAt = sequelize.literal("CURRENT_TIMESTAMP");
+ const user = await this.model.create(friendEntity);
+ user.save();
+ return this.createAmis(user);
+ }
+ async getById(id_utilisateur, amiIdUtilisateur) {
+ const user = await this.model.findOne({
+ where: {
+ id_utilisateur: id_utilisateur,
+ amiIdUtilisateur: amiIdUtilisateur,
+ },
+ });
+ return this.createAmis(user);
+ }
+
+ createAmis(seq) {
+ return seq ? new Friend(seq) : null;
+ }
+
+ async getListFriendsById(id) {
+ const idFriends = await this.model.findAll({
+ attributes: ["amiIdUtilisateur"],
+ where: {
+ id_utilisateur: id,
+ en_attente: false,
+ },
+ });
+
+ let friends = await this.UserModel.findAll({
+ where: {
+ id_utilisateur: {
+ [Op.in]: idFriends.map((f) => f.getDataValue("amiIdUtilisateur")),
+ },
+ },
+ });
+ return friends ? friends.map((f) => new User(f)) : null;
+ }
+
+ async removeFriendById(id_utilisateur, amiIdUtilisateur) {
+ const user = await this.model.destroy({
+ where: {
+ id_utilisateur: id_utilisateur,
+ amiIdUtilisateur: amiIdUtilisateur,
+ },
+ });
+ return user;
+ }
+
+ async getRequestFriendsById(id) {
+ const idFriends = await this.model.findAll({
+ where: {
+ en_attente: true,
+ amiIdUtilisateur: id,
+ },
+ });
+ const friends = await this.UserModel.findAll({
+ where: {
+ id_utilisateur: {
+ [Op.in]: idFriends.map((f) => f.getDataValue("id_utilisateur")),
+ },
+ },
+ });
+ return friends ? friends.map((f) => new User(f)) : null;
+ }
+
+ async getSendRequestFriendsById(id) {
+ const idFriends = await this.model.findAll({
+ where: {
+ en_attente: true,
+ id_utilisateur: id,
+ },
+ });
+ const friends = await this.UserModel.findAll({
+ where: {
+ id_utilisateur: {
+ [Op.in]: idFriends.map((f) => f.getDataValue("amiIdUtilisateur")),
+ },
+ },
+ });
+ return friends ? friends.map((f) => new User(f)) : null;
+ }
+
+ async accept(id, amiIdUtilisateur) {
+ const user = await this.model.update(
+ {
+ en_attente: false,
+ updatedAt: sequelize.literal("CURRENT_TIMESTAMP"),
+ },
+ {
+ where: {
+ id_utilisateur: id,
+ amiIdUtilisateur: amiIdUtilisateur,
+ },
+ }
+ );
+ return this.createAmis(user);
+ }
+
+ async areFriends(id, amiIdUtilisateur) {
+ if (id == amiIdUtilisateur) return true;
+ const count = await this.model.count({
+ where: {
+ [Op.or]: [
+ {
+ id_utilisateur: id,
+ amiIdUtilisateur: amiIdUtilisateur,
+ en_attente: false,
+ },
+ {
+ id_utilisateur: amiIdUtilisateur,
+ amiIdUtilisateur: id,
+ en_attente: false,
+ },
+ ],
+ },
+ });
+ return count > 0;
+ }
+ async doesFollows(id, amiIdUtilisateur) {
+ if (id == amiIdUtilisateur) return true;
+ const count = await this.model.count({
+ where: {
+ [Op.or]: [
+ {
+ id_utilisateur: id,
+ amiIdUtilisateur: amiIdUtilisateur,
+ en_attente: false,
+ },
+ {
+ id_utilisateur: amiIdUtilisateur,
+ amiIdUtilisateur: id,
+ en_attente: false,
+ },
+ ],
+ },
+ });
+ return count > 0;
+ }
+ async getFollowInfo(id_utilisateur, amiIdUtilisateur) {
+ const areFriends = await this.areFriends(id_utilisateur, amiIdUtilisateur);
+ const relation1 = await this.model.findOne({
+ where: {
+ id_utilisateur: id_utilisateur,
+ amiIdUtilisateur: amiIdUtilisateur,
+ },
+ });
+
+ const relation2 = await this.model.findOne({
+ where: {
+ //if the other follows the user
+ id_utilisateur: amiIdUtilisateur,
+ amiIdUtilisateur: id_utilisateur,
+ },
+ });
+ return areFriends
+ ? {
+ areFriends: true,
+ doesFollows: true,
+ isWaiting: false,
+ isWaited: true,
+ isFollowed: true,
+ }
+ : {
+ areFriends: false,
+ doesFollows: !!relation1,
+ isWaiting: relation1 ? !!relation1.en_attente : false,
+ isWaited: relation2 ? !!relation2.en_attente : false,
+ isFollowed: !!relation2,
+ };
+ }
+};
diff --git a/lib/infrastructure/repositories/LikeOeuvreRepository.js b/lib/infrastructure/repositories/LikeOeuvreRepository.js
new file mode 100644
index 0000000..e9c4167
--- /dev/null
+++ b/lib/infrastructure/repositories/LikeOeuvreRepository.js
@@ -0,0 +1,44 @@
+'use strict';
+const sequelize = require('../orm/sequelize/sequelize');
+const LikeOeuvreRepositoryAbstract = require('./interfaces/LikeOeuvreRepositoryAbstract')
+module.exports = class extends LikeOeuvreRepositoryAbstract {
+ constructor() {
+ super();
+ this.db = sequelize;
+ this.likeOeuvre = this.db.model('like_oeuvre');
+ }
+
+ like(userId, oeuvreId) {
+ this.likeOeuvre.create({
+ id_oeuvre: oeuvreId,
+ id_user: userId
+ })
+ }
+
+ unlike(userId, oeuvreId) {
+ this.likeOeuvre.destroy({
+ where: {
+ id_oeuvre: oeuvreId,
+ id_user: userId
+ }
+ })
+ }
+ doesUserLikes(userId, oeuvreId) {
+ return this.likeOeuvre.findOne({
+ where: {
+ id_oeuvre: oeuvreId,
+ id_user: userId
+ }
+ }).then(like => {
+ return !!like
+ })
+ }
+ getLikeCount(oeuvreId) {
+ return this.likeOeuvre.count({
+ where: {
+ id_oeuvre: oeuvreId,
+ }
+ }).then(count => count)
+ }
+
+};
diff --git a/lib/infrastructure/repositories/NodemailerRepository.js b/lib/infrastructure/repositories/NodemailerRepository.js
new file mode 100644
index 0000000..3f68eec
--- /dev/null
+++ b/lib/infrastructure/repositories/NodemailerRepository.js
@@ -0,0 +1,23 @@
+'use strict';
+const MailRepositoryAbstract = require('./interfaces/MailRepositoryAbstract')
+const nodemailer = require('nodemailer')
+module.exports = class extends MailRepositoryAbstract{
+ constructor(service, user, pass) {
+ super();
+ this.transporter = nodemailer.createTransport({
+ service,
+ auth: {
+ user,
+ pass
+ }
+ })
+ }
+ send(config) {
+ this.transporter.sendMail(config)
+ }
+
+
+
+
+
+};
diff --git a/lib/infrastructure/repositories/OeuvreFavRepository.js b/lib/infrastructure/repositories/OeuvreFavRepository.js
new file mode 100644
index 0000000..6b8ad83
--- /dev/null
+++ b/lib/infrastructure/repositories/OeuvreFavRepository.js
@@ -0,0 +1,72 @@
+'use strict';
+
+
+const sequelize = require('../orm/sequelize/sequelize');
+const { Op } = require('sequelize');
+const OeuvreFav = require('../../domain/model/OeuvreFav.js');
+const OeuvreFavRepositoryAbstract = require('./interfaces/OeuvreFavRepositoryAbstract');
+
+module.exports = class extends OeuvreFavRepositoryAbstract { // creer abstract
+
+ constructor() {
+ super();
+ this.db = sequelize;
+ this.oeuvreFav = this.db.model('oeuvre_favorite');
+ this.oeuvresFavMax = 3;
+ }
+ createOeuvre(oeuvre) {
+ return oeuvre ? new OeuvreFav(oeuvre.dataValues) : null
+ }
+ async ajoutPossible(idUtilisateur){
+ let nbOeuvresFav = await this.oeuvreFav.count({
+ where: {
+ id_utilisateur: idUtilisateur
+ },
+ });
+ return nbOeuvresFav < this.oeuvresFavMax;
+ }
+
+ async addOeuvrefav(idUtilisateur, idOeuvre,type) {
+ if(!await this.ajoutPossible(idUtilisateur)) return false
+ const seqUser = await this.oeuvreFav.create({
+ id_utilisateur: idUtilisateur,
+ id_oeuvre: idOeuvre,
+ createdAt: sequelize.literal('CURRENT_TIMESTAMP'),
+ updatedAt: sequelize.literal('CURRENT_TIMESTAMP'),
+ type
+ })
+ await seqUser.save()
+ }
+
+ async deleteOeuvrefav(idUtilisateur, idOeuvre) {
+ const seqUser = await this.oeuvreFav.destroy({
+ where: {
+ id_utilisateur: idUtilisateur,
+ id_oeuvre: idOeuvre,
+ }
+ })
+ }
+
+ async oeuvreFavExists(idUtilisateur, idOeuvre) {
+ let oeuvre = await this.oeuvreFav.findOne({
+ where: {
+ [Op.and]: {
+ id_utilisateur: idUtilisateur,
+ id_oeuvre: idOeuvre,
+ }
+ }
+ })
+ return !!oeuvre
+ }
+
+ async getOeuvresFav(idUtilisateur) {
+ let oeuvresFav = await this.oeuvreFav.findAll({
+ where: {
+ id_utilisateur: idUtilisateur
+ },
+ });
+ return oeuvresFav ? oeuvresFav.map(oeuvre => this.createOeuvre(oeuvre)) : null;
+ }
+
+};
+
diff --git a/lib/infrastructure/repositories/ReviewRepository.js b/lib/infrastructure/repositories/ReviewRepository.js
new file mode 100644
index 0000000..d15caa7
--- /dev/null
+++ b/lib/infrastructure/repositories/ReviewRepository.js
@@ -0,0 +1,354 @@
+"use strict";
+
+const sequelize = require("../orm/sequelize/sequelize");
+const ReviewRepository = require("./interfaces/ReviewRepositoryAbstract");
+const { Op } = require("sequelize");
+const User = require("../../domain/model/User");
+const Review = require("../../domain/model/Review");
+const { get } = require("underscore");
+const getPreWhere = (fetchPrivate, id, friendsOnly) => {
+ let whereClause = {
+ deleted: false,
+ };
+ if (!fetchPrivate) {
+ if (friendsOnly && id) {
+ whereClause.id_utilisateur = {
+ [Op.in]: sequelize.literal(
+ `(SELECT id_utilisateur FROM utilisateur WHERE id_utilisateur IN (SELECT id_utilisateur FROM amis WHERE amiIdUtilisateur = ${id} and en_attente = false) OR id_utilisateur IN (SELECT amiIdUtilisateur FROM amis WHERE id_utilisateur = ${id} and en_attente = false))`
+ ),
+ };
+ } else {
+ whereClause.id_utilisateur = id
+ ? {
+ [Op.in]: sequelize.literal(
+ `(SELECT id_utilisateur FROM utilisateur WHERE is_private = false OR id_utilisateur=${id} OR id_utilisateur IN (SELECT id_utilisateur FROM amis WHERE amiIdUtilisateur = ${id} and en_attente = false) OR id_utilisateur IN (SELECT amiIdUtilisateur FROM amis WHERE id_utilisateur = ${id} and en_attente = false))`
+ ),
+ }
+ : {
+ [Op.in]: sequelize.literal(
+ `(SELECT id_utilisateur FROM utilisateur WHERE is_private = false`
+ ),
+ };
+ }
+ }
+ return whereClause;
+};
+module.exports = class extends ReviewRepository {
+ constructor() {
+ super();
+ this.db = sequelize;
+ this.review = this.db.model("review");
+ this.TypeReview = this.db.model("type_review");
+ this.user = this.db.model("utilisateur");
+ this.likeReviewModel = this.db.model("like_review");
+ }
+ createReview(seqReview) {
+ if (!seqReview) return null;
+ const type = seqReview.type_review.dataValues.libelle;
+ return new Review(seqReview, new User(seqReview.utilisateur), type);
+ }
+ async persist(ReviewEntity) {
+ let seqReview = await this.review.create(ReviewEntity, {
+ include: [
+ {
+ model: this.user,
+ as: "utilisateur",
+ attributes: ["alias"],
+ },
+ ],
+ });
+ return this.getById(seqReview.id_review);
+ }
+ async getByUserAndId(id_oeuvre, id_utilisateur) {
+ return await this.review.findOne({
+ where: {
+ id_oeuvre,
+ id_utilisateur,
+ deleted: false,
+ },
+ });
+ }
+ async getTypeReviewID(label) {
+ const seqTypeReview = await this.TypeReview.findOne({
+ where: {
+ libelle: label,
+ },
+ });
+ return seqTypeReview?.id_type_review;
+ }
+
+ async delete(id_review, id_utilisateur) {
+ const seqReview = await this.review.findOne({
+ where: {
+ id_review,
+ id_utilisateur,
+ },
+ });
+ if (!seqReview) return false;
+ seqReview.deleted = true;
+ seqReview.save();
+ return true;
+ }
+ async getById(id_review, deleted = false) {
+ const seqReview = await this.review.findOne({
+ where: {
+ id_review: id_review,
+ deleted,
+ },
+ attributes: {
+ include: [
+ [
+ sequelize.literal(
+ "(SELECT COUNT(DISTINCT like_review.id_utilisateur ) FROM like_review WHERE like_review.id_review = review.id_review)"
+ ),
+ "countLike",
+ ],
+ [
+ sequelize.literal(
+ "(SELECT COUNT(*) FROM commentaire WHERE commentaire.id_review = review.id_review and commentaire.deleted = false and commentaire.id_reponse = null)"
+ ),
+ "countComment",
+ ],
+ ],
+ },
+ include: [
+ {
+ model: this.user,
+ as: "utilisateur",
+ },
+ {
+ model: this.TypeReview,
+ attributes: ["libelle"],
+ as: "type_review",
+ },
+ ],
+ });
+ return this.createReview(seqReview);
+ }
+
+ async getReviews(page, pageSize, orderByLike, fetchPrivate, friendsOnly, id) {
+ const orderColumn = orderByLike ? "countLike" : "createdAt";
+ const order = [[sequelize.literal(orderColumn), "DESC"]];
+ const offset = (page - 1) * pageSize;
+ let whereClause = getPreWhere(fetchPrivate, id, friendsOnly);
+ const reviews = await this.review.findAll({
+ limit: pageSize,
+ offset: offset,
+ attributes: {
+ include: [
+ [
+ sequelize.literal(
+ "(SELECT COUNT(*) FROM like_review WHERE like_review.id_review = review.id_review)"
+ ),
+ "countLike",
+ ],
+ [
+ sequelize.literal(
+ "(SELECT COUNT(*) FROM commentaire WHERE commentaire.id_review = review.id_review and commentaire.deleted = false and commentaire.id_reponse = null)"
+ ),
+ "countComment",
+ ],
+ ],
+ },
+ include: [
+ {
+ model: this.user,
+ as: "utilisateur",
+ },
+ {
+ model: this.TypeReview,
+ attributes: ["libelle"],
+ as: "type_review",
+ },
+ ],
+ order,
+ where: whereClause,
+ });
+ return reviews.map((item) => this.createReview(item));
+ }
+
+ async getOeuvreReviews(
+ page,
+ pageSize,
+ orderByLike,
+ fetchPrivate,
+ friendsOnly,
+ ids_oeuvre,
+ id
+ ) {
+ const orderColumn = orderByLike ? "countLike" : "createdAt";
+ const order = [[sequelize.literal(orderColumn), "DESC"]];
+ const offset = (page - 1) * pageSize;
+ let whereClause = getPreWhere(fetchPrivate, id, friendsOnly);
+ if (Array.isArray(ids_oeuvre) && ids_oeuvre.length > 0) {
+ whereClause.id_oeuvre = { [Op.in]: ids_oeuvre };
+ } else {
+ whereClause.id_oeuvre = ids_oeuvre;
+ }
+
+ const reviews = await this.review.findAll({
+ limit: pageSize,
+ offset: offset,
+ attributes: {
+ include: [
+ [
+ sequelize.literal(
+ "(SELECT COUNT(*) FROM like_review WHERE like_review.id_review = review.id_review)"
+ ),
+ "countLike",
+ ],
+ [
+ sequelize.literal(
+ "(SELECT COUNT(*) FROM commentaire WHERE commentaire.id_review = review.id_review and commentaire.deleted = false and commentaire.id_reponse = null)"
+ ),
+ "countComment",
+ ],
+ ],
+ },
+ include: [
+ {
+ model: this.user,
+ as: "utilisateur",
+ },
+ {
+ model: this.TypeReview,
+ attributes: ["libelle"],
+ as: "type_review",
+ },
+ ],
+ order,
+ where: whereClause,
+ });
+ return reviews.map((item) => this.createReview(item));
+ }
+ async doesUserLikes(id_utilisateur, id_review) {
+ const count = await this.likeReviewModel.count({
+ where: {
+ id_utilisateur,
+ id_review,
+ },
+ });
+ return count > 0;
+ }
+ async likeReview(id_utilisateur, id_review) {
+ const seqLike = await this.likeReviewModel.create({
+ id_review,
+ id_utilisateur,
+ });
+ await seqLike.save();
+ }
+ async unlikeReview(id_utilisateur, id_review) {
+ await this.likeReviewModel.destroy({
+ where: {
+ id_utilisateur,
+ id_review,
+ },
+ });
+ }
+ async getLikes(id_utilisateur, id_review, page, pageSize) {
+ const offset = (page - 1) * pageSize;
+ const whereClause = {};
+ whereClause["$review_like->like_review.id_review$"] = id_review;
+ whereClause.id_utilisateur = id_utilisateur
+ ? {
+ [Op.in]: sequelize.literal(
+ `(SELECT id_utilisateur FROM utilisateur WHERE is_private = false OR id_utilisateur=${id_utilisateur} OR id_utilisateur IN (SELECT id_utilisateur FROM amis WHERE amiIdUtilisateur = ${id_utilisateur}))`
+ ),
+ }
+ : {
+ [Op.in]: sequelize.literal(
+ "(SELECT id_utilisateur FROM utilisateur WHERE is_private = false)"
+ ),
+ };
+ const reviews = await this.review.findAll({
+ offset: offset,
+ include: [
+ {
+ model: this.user,
+ as: "review_like",
+ where: whereClause,
+ },
+ ],
+ });
+ const limit =
+ reviews[0]?.review_like.length > pageSize
+ ? pageSize
+ : reviews[0]?.review_like.length;
+ return reviews[0]?.review_like
+ ? reviews[0]?.review_like.slice(0, limit)
+ : [];
+ }
+
+ async getReviewByUserId(id_utilisateur, page, pageSize, orderByLike) {
+ const offset = (page - 1) * pageSize;
+ const orderColumn = orderByLike ? "countLike" : "createdAt";
+ const order = [[sequelize.literal(orderColumn), "DESC"]];
+
+ const reviews = await this.review.findAll({
+ offset: offset,
+ limit: pageSize,
+ attributes: {
+ include: [
+ [
+ sequelize.literal(
+ "(SELECT COUNT(*) FROM like_review WHERE like_review.id_review = review.id_review)"
+ ),
+ "countLike",
+ ],
+ [
+ sequelize.literal(
+ "(SELECT COUNT(*) FROM commentaire WHERE commentaire.id_review = review.id_review and commentaire.deleted = false and commentaire.id_reponse = null)"
+ ),
+ "countComment",
+ ],
+ ],
+ },
+ include: [
+ {
+ model: this.user,
+ as: "utilisateur",
+ },
+ {
+ model: this.TypeReview,
+ attributes: ["libelle"],
+ as: "type_review",
+ },
+ ],
+ where: {
+ id_utilisateur,
+ deleted: false,
+ },
+ order,
+ });
+ return reviews.map((item) => this.createReview(item));
+ }
+
+ async getOeuvreRating(id_oeuvre) {
+ const seqReview = await this.review.findOne({
+ where: {
+ id_oeuvre,
+ deleted: false,
+ },
+ attributes: [[sequelize.fn("AVG", sequelize.col("note")), "rating"]],
+ });
+ return seqReview.dataValues.rating;
+ }
+
+ async doesUserLike(id_utilisateur, id_review) {
+ return !!(await this.likeReviewModel.findOne({
+ where: {
+ id_utilisateur,
+ id_review,
+ },
+ }));
+ }
+
+ async getReviewCount(id_oeuvre) {
+ return await this.review.count({
+ where: {
+ id_oeuvre,
+ deleted: false,
+ },
+ });
+ }
+};
diff --git a/lib/infrastructure/repositories/SpotifyRepository.js b/lib/infrastructure/repositories/SpotifyRepository.js
index 5789ba4..239b4e1 100644
--- a/lib/infrastructure/repositories/SpotifyRepository.js
+++ b/lib/infrastructure/repositories/SpotifyRepository.js
@@ -4,41 +4,170 @@ const axios = require("axios");
const spotifyRepositoryAbstract = require('./interfaces/SpotifyRepositoryAbstract')
module.exports = class extends spotifyRepositoryAbstract{
- constructor(client_id,client_secret) {
- super();
- this.client_id = client_id
- this.client_secret = client_secret
- }
+ constructor(client_id,client_secret) {
+ super();
+ this.client_id = client_id
+ this.client_secret = client_secret
+ }
- getSpotifyAccessToken() {
+ getSpotifyAccessToken() {
+ return axios.post('https://accounts.spotify.com/api/token', null, {
+ params: {
+ grant_type: 'client_credentials',
+ },
+ auth: {
+ username: this.client_id,
+ password: this.client_secret,
+ },
+ }).then((response) => {
+ return response.data.access_token
+ })
+ }
- return axios.post('https://accounts.spotify.com/api/token', null, {
- params: {
- grant_type: 'client_credentials',
- },
- auth: {
- username: this.client_id,
- password: this.client_secret,
- },
- }).then((response) => {
- return response.data.access_token
- })
- }
+
async getSpotifySearchList(query,filter,limit){
- return axios.get('https://api.spotify.com/v1/search', {
- headers: {
- 'Authorization': `Bearer ${await this.getSpotifyAccessToken()}`,
- },
- params: {
- q: query,
- type: filter,
- limit : limit
- },
- })
+ return axios.get('https://api.spotify.com/v1/search', {
+ headers: {
+ 'Authorization': `Bearer ${await this.getSpotifyAccessToken()}`,
+ },
+ params: {
+ q: query,
+ type: filter,
+ limit : limit
+ },
+ })
.then((response) => {
return response.data
})
}
+ async getSpotifyArtist(id){
+ return axios.get(`https://api.spotify.com/v1/artists/${id}`, {
+ validateStatus: function (status) {
+ return true;
+ },
+ headers: {
+ 'Authorization': `Bearer ${await this.getSpotifyAccessToken()}`,
+ },
+ })
+ .then((response) => {
+ return response.data
+ })
+ }
+
+ async getSpotifyAlbums(id){
+ return axios.get('https://api.spotify.com/v1/albums/'+ id, {
+ validateStatus: function (status) {
+ return true;
+ },
+ headers: {
+ 'Authorization': `Bearer ${await this.getSpotifyAccessToken()}`,
+ }
+ })
+ .then((response) => {
+ return response.data
+ })
+ }
+ async getSpotifyArtist(id){
+ return axios.get(`https://api.spotify.com/v1/artists/${id}`, {
+ validateStatus: function (status) {
+ return true;
+ },
+ headers: {
+ 'Authorization': `Bearer ${await this.getSpotifyAccessToken()}`,
+ },
+ })
+ .then((response) => {
+ return response.data
+ })
+ }
+
+ async getSpotifyTracks(id){
+ return axios.get('https://api.spotify.com/v1/tracks/'+ id, {
+ validateStatus: function (status) {
+ return true;
+ },
+ headers: {
+ 'Authorization': `Bearer ${await this.getSpotifyAccessToken()}`,
+ }
+ })
+ .then((response) => {
+ return response.data
+ })
+ }
+
+ refreshToken(token) {
+ const payload = new URLSearchParams()
+ payload.append('grant_type', 'refresh_token');
+ payload.append('refresh_token', token);
+ return axios.post('https://accounts.spotify.com/api/token',payload,{
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ },
+ auth: {
+ username: this.client_id,
+ password: this.client_secret,
+ },
+ })
+ .then((response) => {
+ return response.data
+ })
+ }
+ getToken(code,redirectURI) {
+ const payload = new URLSearchParams()
+ payload.append('grant_type','authorization_code')
+ payload.append('redirect_uri',redirectURI)
+ payload.append('code',code)
+ return axios.post('https://accounts.spotify.com/api/token',payload,
+ {
+ validateStatus: function (status) {
+ return true;
+ },
+ headers: {
+ 'content-type': 'application/x-www-form-urlencoded',
+ 'Authorization': 'Basic ' + (new Buffer.from(this.client_id + ':' + this.client_secret).toString('base64'))
+ },
+ })
+ .then((response) => {
+ return response.data
+ })
+ }
+ getAccountData(accessToken) {
+ return axios.get('https://api.spotify.com/v1/me', {
+ headers: {
+ 'Authorization': `Bearer ${accessToken}`,
+ 'Content-Type': 'application/json',
+ },
+ })
+ .then(response => {
+ return response.data
+ })
+ }
+ async getSpotifyArtistSongs(id, filter, limit) {
+ return axios.get(`https://api.spotify.com/v1/artists/${id}/albums`, {
+ validateStatus: function (status) {
+ return true; // axios traite les reponses tjs en reussites
+ },
+ headers: {
+ 'Authorization': `Bearer ${await this.getSpotifyAccessToken()}`,
+ },
+ params: {
+ include_groups: filter, // N'APPARAIT PAS DANS LES PARAMS DE LA REQUETE https://developer.spotify.com/documentation/web-api/reference/get-an-artists-albums
+ limit: limit
+ },
+ })
+ .then((response) => {
+ return response.data
+ })
+ }
+ getOeuvre(id,type) {
+ switch (type) {
+ case 'artist': return this.getSpotifyArtist(id)
+ case 'album': return this.getSpotifyAlbums(id)
+ case 'track': return this.getSpotifyTracks(id)
+ default:
+ return {error: {status: 404, message: 'ressource not found'}}
+ }
+ }
};
diff --git a/lib/infrastructure/repositories/UserRepository.js b/lib/infrastructure/repositories/UserRepository.js
index e8e94ab..1178ac9 100644
--- a/lib/infrastructure/repositories/UserRepository.js
+++ b/lib/infrastructure/repositories/UserRepository.js
@@ -3,9 +3,7 @@
const sequelize = require('../orm/sequelize/sequelize');
const user = require('../../domain/model/User');
const userRepository = require('./interfaces/UserRepositoryAbstract');
-const { Op } = require('sequelize');
-const {id} = require("../../domain/model/User");
-const {create} = require("underscore");
+const { Op} = require('sequelize');
module.exports = class extends userRepository {
constructor() {
@@ -15,17 +13,7 @@ module.exports = class extends userRepository {
}
async persist(userEntity) {
- const { pseudo, email, password,alias, bio, id_role,id_etat,spotifyToken } = userEntity;
- const seqUser = await this.model.create({
- pseudo : pseudo,
- email : email,
- alias : alias,
- bio : bio,
- password : password,
- token_spotify : spotifyToken,
- id_role : id_role,
- id_etat : id_etat });
-
+ const seqUser = await this.model.create(userEntity);
await seqUser.save();
return this.createUser(seqUser)
}
@@ -38,7 +26,7 @@ module.exports = class extends userRepository {
{ pseudo : ident},
{ email : ident}
]
- }
+ },
});
return this.createUser(seqUser)
}
@@ -48,23 +36,15 @@ module.exports = class extends userRepository {
createUser(seqUser){
if(!seqUser) return null
- return new user(seqUser.id_utilisateur,
- seqUser.pseudo,
- seqUser.email,
- seqUser.alias,
- seqUser.bio,
- seqUser.password,
- seqUser.token_spotify,
- seqUser.id_role,
- seqUser.id_etat);
+ return new user(seqUser.dataValues);
}
async getByEmailOrPseudo(email, pseudo){
const seqUser = await this.model.findOne({
where: {
- [Op.or]: [
- { pseudo : email},
- { email : pseudo}
- ]
+ [Op.or]: {
+ pseudo: pseudo,
+ email: email,
+ }
}
});
return this.createUser(seqUser)
@@ -74,15 +54,147 @@ module.exports = class extends userRepository {
let request = {where: {pseudo : {[Op.like]: `${pseudo}%`}}}
if(limit) request.limit = limit
let seqUsers = await this.model.findAll(request);
- seqUsers = seqUsers.map(item => this.createUser(item.dataValues))
+ seqUsers = seqUsers.map(item => this.createUser(item))
return Object.values(seqUsers);
}
async getByUser(id){
- const seqUser = await this.model.findOne({
+ const seqUser = await this.model.findOne(
+ {
+ attributes: {
+ include: [
+ [
+ sequelize.literal('(SELECT COUNT(*) FROM amis WHERE amis.id_utilisateur = utilisateur.id_utilisateur AND en_attente=false)'),
+ 'following_count'
+ ],
+ [
+ sequelize.literal('(SELECT COUNT(*) FROM amis WHERE amis.amiIdUtilisateur = utilisateur.id_utilisateur AND en_attente=false)'),
+ 'follower_count'
+ ],
+ [
+ sequelize.literal('(SELECT COUNT(*) FROM review WHERE review.id_utilisateur = utilisateur.id_utilisateur)'),
+ 'review_count'
+ ],
+ ]
+ },
where: {
id_utilisateur : id
}
});
return this.createUser(seqUser)
}
+ async getPreviewPath(id){
+ const url = await this.model.findOne({
+ where: {
+ [Op.and]: [
+ { id_utilisateur: id },
+ sequelize.literal('NOT `photo_temporaire` <=> `photo`'),
+ ]
+ },
+ attributes: ['photo_temporaire'],
+ raw:true
+ });
+ return url?.photo_temporaire
+ }
+ async addPreviewPath(id,path){
+ const [updatedRowsCount, updatedRows] = await this.model.update(
+ {photo_temporaire: path},
+ {where: {id_utilisateur: id}}
+ )
+ return updatedRowsCount
+ }
+ async updateUser(user){
+ const { pseudo, email, password,alias, bio, id_role,ban_until,token,refresh_token,confirmed,confirm_token,photo, photo_temporaire, reset_token} = user;
+ const seqUser = await this.model.findOne({
+ where: {
+ id_utilisateur : user.id_utilisateur
+ }
+ });
+ for (let attribut in user) {
+ if (user.hasOwnProperty(attribut)) {
+ seqUser[attribut] = user[attribut];
+ }
+ }
+ seqUser.save()
+ }
+ async getSpotifyAuthUser(){
+ let seqUsers = await this.model.findAll({
+ where: {
+ token: {[Op.not]: null}
+ }
+ });
+ seqUsers = seqUsers.map(item => this.createUser(item.dataValues))
+ return seqUsers;
+ }
+ async removeUserByConfirmToken(confirmToken){
+ const seqUsers = await this.model.findOne({
+ where: {
+ confirm_token: confirmToken
+ }
+ });
+ if(seqUsers) {
+ await seqUsers.destroy()
+ }
+ }
+ removeUncheckedAccounts() {
+ const twentyFourHoursAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
+ this.model.destroy({
+ where: {
+ [Op.and]: [
+ {updatedAt: {
+ [Op.lt]: twentyFourHoursAgo
+ }},
+ {confirmed: false}
+ ]
+
+ }
+ })
+ }
+ destroy(user) {
+ this.model.destroy({
+ where: {
+ id_utilisateur: user.id_utilisateur
+ }
+ })
+ }
+ async getByConfirmToken(token) {
+ const seqUsers = await this.model.findOne({
+ where: {
+ confirm_token: token
+ }
+ });
+ return this.createUser(seqUsers)
+ }
+ clearResetTokens() {
+ this.model.update({
+ reset_token: null
+ },{ where: {reset_token: {[Op.not]: null}} })
+ }
+ async getByResetToken(resetToken) {
+ const seqUsers = await this.model.findOne({
+ where: {
+ reset_token: resetToken
+ }
+ });
+ return this.createUser(seqUsers)
+ }
+
+ async changePrivateStatus(id){
+ const user = await this.model.findOne({
+ where: {id_utilisateur: id}
+ });
+
+ if (user) {
+ const nouveauStatut = user.is_private ? false : true;
+
+ await this.model.update(
+ { is_private: nouveauStatut },
+ { where: { id_utilisateur: id } }
+ );
+
+ }
+
+ return this.createUser(user);
+}
+
};
+
diff --git a/lib/infrastructure/repositories/interfaces/CommentRepositoryAbstract.js b/lib/infrastructure/repositories/interfaces/CommentRepositoryAbstract.js
new file mode 100644
index 0000000..45bf5c3
--- /dev/null
+++ b/lib/infrastructure/repositories/interfaces/CommentRepositoryAbstract.js
@@ -0,0 +1,44 @@
+"use strict";
+
+module.exports = class {
+ persist(id_review, description, id_utilisateur) {
+ throw new Error("ERR_METHOD_NOT_IMPLEMENTED");
+ }
+
+ getReviewComments(
+ id_review,
+ id_utilisateur,
+ fetchPrivate,
+ page,
+ pageSize,
+ orderByLike
+ ) {
+ throw new Error("ERR_METHOD_NOT_IMPLEMENTED");
+ }
+ getCommentsComments(
+ id_reponse,
+ id_utilisateur,
+ fetchPrivate,
+ page,
+ pageSize,
+ orderByLike
+ ) {
+ throw new Error("ERR_METHOD_NOT_IMPLEMENTED");
+ }
+ delete(id_comment, id_utilisateur) {
+ throw new Error("ERR_METHOD_NOT_IMPLEMENTED");
+ }
+ doesUserLikes(id_comment, id_utilisateur) {
+ throw new Error("ERR_METHOD_NOT_IMPLEMENTED");
+ }
+ like(id_comment, id_utilisateur) {
+ throw new Error("ERR_METHOD_NOT_IMPLEMENTED");
+ }
+ unlike(id_comment, id_utilisateur) {
+ throw new Error("ERR_METHOD_NOT_IMPLEMENTED");
+ }
+
+ canDelete(id_comment, id_utilisateur) {
+ throw new Error("ERR_METHOD_NOT_IMPLEMENTED");
+ }
+};
diff --git a/lib/infrastructure/repositories/interfaces/DoucumentRepositoryAbstract.js b/lib/infrastructure/repositories/interfaces/DoucumentRepositoryAbstract.js
new file mode 100644
index 0000000..3ff027f
--- /dev/null
+++ b/lib/infrastructure/repositories/interfaces/DoucumentRepositoryAbstract.js
@@ -0,0 +1,16 @@
+'use strict';
+
+module.exports = class {
+
+ uploadFile(path,file) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ deleteFile(path){
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+
+
+
+
+
+};
diff --git a/lib/infrastructure/repositories/interfaces/FollowRepositoryAbstract.js b/lib/infrastructure/repositories/interfaces/FollowRepositoryAbstract.js
new file mode 100644
index 0000000..7ad4b98
--- /dev/null
+++ b/lib/infrastructure/repositories/interfaces/FollowRepositoryAbstract.js
@@ -0,0 +1,25 @@
+'use strict';
+
+module.exports = class {
+
+ follow(userId, artistId) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+
+ unfollow(userId, artistId) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ doesFollows(userId, artistId) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ getFollowersCount(idArtist) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ getFriendsFollowing(idArtist,idUser,limit) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+
+ async getFriendsFollowingCount(idArtist,idUser) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+};
diff --git a/lib/infrastructure/repositories/interfaces/FriendRepositoryAbstract.js b/lib/infrastructure/repositories/interfaces/FriendRepositoryAbstract.js
new file mode 100644
index 0000000..59d5e4e
--- /dev/null
+++ b/lib/infrastructure/repositories/interfaces/FriendRepositoryAbstract.js
@@ -0,0 +1,28 @@
+"use strict";
+
+module.exports = class {
+ persist(friendEntity) {
+ throw new Error("ERR_METHOD_NOT_IMPLEMENTED");
+ }
+
+ getById(id_utilisateur, amiIdUtilisateur) {
+ throw new Error("ERR_METHOD_NOT_IMPLEMENTED");
+ }
+ getListFriendsById(id) {
+ throw new Error("ERR_METHOD_NOT_IMPLEMENTED");
+ }
+ removeFriendById(id_utilisateur, amiIdUtilisateur) {
+ throw new Error("ERR_METHOD_NOT_IMPLEMENTED");
+ }
+ getRequestFriendsById(id) {
+ throw new Error("ERR_METHOD_NOT_IMPLEMENTED");
+ }
+
+ accept(id, amiIdUtilisateur) {
+ throw new Error("ERR_METHOD_NOT_IMPLEMENTED");
+ }
+
+ areFriends(id, amiIdUtilisateur) {
+ throw new Error("ERR_METHOD_NOT_IMPLEMENTED");
+ }
+};
diff --git a/lib/infrastructure/repositories/interfaces/LikeOeuvreRepositoryAbstract.js b/lib/infrastructure/repositories/interfaces/LikeOeuvreRepositoryAbstract.js
new file mode 100644
index 0000000..7629927
--- /dev/null
+++ b/lib/infrastructure/repositories/interfaces/LikeOeuvreRepositoryAbstract.js
@@ -0,0 +1,19 @@
+'use strict';
+
+module.exports = class {
+
+ like(userId, oeuvreId) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+
+ unlike(userId, oeuvreId) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ doesUserLikes(userId, oeuvreId) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ getLikeCount(oeuvreId) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+
+};
diff --git a/lib/infrastructure/repositories/interfaces/MailRepositoryAbstract.js b/lib/infrastructure/repositories/interfaces/MailRepositoryAbstract.js
new file mode 100644
index 0000000..7bf6f6c
--- /dev/null
+++ b/lib/infrastructure/repositories/interfaces/MailRepositoryAbstract.js
@@ -0,0 +1,14 @@
+'use strict';
+
+module.exports = class {
+
+ send(config) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+
+
+
+
+
+
+};
diff --git a/lib/infrastructure/repositories/interfaces/OeuvreFavRepositoryAbstract.js b/lib/infrastructure/repositories/interfaces/OeuvreFavRepositoryAbstract.js
new file mode 100644
index 0000000..47a268b
--- /dev/null
+++ b/lib/infrastructure/repositories/interfaces/OeuvreFavRepositoryAbstract.js
@@ -0,0 +1,20 @@
+'use strict';
+
+module.exports = class {
+
+ addOeuvrefav(idUtilisateur, idOeuvre) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ deleteOeuvrefav(idUtilisateur, idOeuvre) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ oeuvreFavExists(idUtilisateur, idOeuvre) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ getOeuvresFav(idUtilisateur) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ ajoutPossible(idUtilisateur) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+};
diff --git a/lib/infrastructure/repositories/interfaces/ReviewRepositoryAbstract.js b/lib/infrastructure/repositories/interfaces/ReviewRepositoryAbstract.js
new file mode 100644
index 0000000..ec03b20
--- /dev/null
+++ b/lib/infrastructure/repositories/interfaces/ReviewRepositoryAbstract.js
@@ -0,0 +1,55 @@
+'use strict';
+
+module.exports = class {
+
+ persist(review) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+
+ getByUserAndId(id_oeuvre,id_utilisateur) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ delete(id_oeuvre,id_utilisateur) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ getTypeReviewID(label){
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+
+ getById(id_review) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+
+ getReviews(page,pageSize,orderByLike) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ doesUserLikes(id_utilisateur,id_review) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ likeReview(id_utilisateur,id_review) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ unlikeReview(id_utilisateur,id_review) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ getLikes(id_utilisateur,id_review,page,pageSize) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ getReviewByUserId(id_utilisateur,pageSize,orderByLike) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+
+ getOeuvreReviews(page,pageSize,orderByLike, fetchPrivate, ids_oeuvre,id) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ doesUserLike(id_utilisateur,id_review) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ getOeuvreRating(id_oeuvre) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+
+ getReviewCount(id_oeuvre) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+};
diff --git a/lib/infrastructure/repositories/interfaces/SpotifyRepositoryAbstract.js b/lib/infrastructure/repositories/interfaces/SpotifyRepositoryAbstract.js
index 12059c5..bc78173 100644
--- a/lib/infrastructure/repositories/interfaces/SpotifyRepositoryAbstract.js
+++ b/lib/infrastructure/repositories/interfaces/SpotifyRepositoryAbstract.js
@@ -10,7 +10,24 @@ module.exports = class {
throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
}
+ async getSpotifyArtist(id){
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ refreshToken(token) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ getToken(code,redirectURI) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ getAccountData(accessToken){
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
-
+ async getSpotifyArtist(id){
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ getOeuvre(id) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
};
diff --git a/lib/infrastructure/repositories/interfaces/UserRepositoryAbstract.js b/lib/infrastructure/repositories/interfaces/UserRepositoryAbstract.js
index 22f2528..4ff7da4 100644
--- a/lib/infrastructure/repositories/interfaces/UserRepositoryAbstract.js
+++ b/lib/infrastructure/repositories/interfaces/UserRepositoryAbstract.js
@@ -19,5 +19,38 @@ module.exports = class {
async getByUser(id){
throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
}
+ async getPreviewPath(id){
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ async addPreviewPath(id,path){
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ updateUser(user){
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ getSpotifyAuthUser(){
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ removeUserByConfirmToken(confirmToken){
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ removeUncheckedAccounts() {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ getByConfirmToken(token) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ clearResetTokens() {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ getByResetToken(resetToken) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ destroy(user) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
+ setPrivateStatus(id) {
+ throw new Error('ERR_METHOD_NOT_IMPLEMENTED');
+ }
};
diff --git a/lib/infrastructure/routine/refreshTokens.js b/lib/infrastructure/routine/refreshTokens.js
new file mode 100644
index 0000000..f7a7341
--- /dev/null
+++ b/lib/infrastructure/routine/refreshTokens.js
@@ -0,0 +1,7 @@
+const refreshToken = require("../../application/use_cases/spotify/RefreshToken")
+module.exports = async ({spotifyRepository, userRepository}) => {
+ const users = await userRepository.getSpotifyAuthUser()
+ for(let i = 0; i {
+ userRepository.removeUncheckedAccounts()
+ userRepository.clearResetTokens()
+}
\ No newline at end of file
diff --git a/lib/infrastructure/security/JwtAccessTokenManager.js b/lib/infrastructure/security/JwtAccessTokenManager.js
index 6ae9ff9..fd297f5 100644
--- a/lib/infrastructure/security/JwtAccessTokenManager.js
+++ b/lib/infrastructure/security/JwtAccessTokenManager.js
@@ -4,11 +4,15 @@ const jwt = require('jsonwebtoken');
const AccessTokenManager = require('./AccessTokenManager');
const JWT_SECRET_KEY = process.env.SECRET_ENCODER;
-
module.exports = class extends AccessTokenManager {
- generate(payload) {
- return jwt.sign(payload, JWT_SECRET_KEY);
+ generate(user) {
+ return jwt.sign({
+ sub: 'my-sub', // needs to match definition above
+ value: user.id_utilisateur, // this is a custom key I used, it could be named anything. Value should be a way to authenticate the user
+ aud: 'urn:audience:test', // needs to match definition above
+ iss: 'urn:issuer:test', // needs to match definition above,
+ }, JWT_SECRET_KEY,{ expiresIn: '999y' });
}
decode(accessToken) {
diff --git a/lib/infrastructure/webserver/server.js b/lib/infrastructure/webserver/server.js
index 9317bf7..0a7a19b 100644
--- a/lib/infrastructure/webserver/server.js
+++ b/lib/infrastructure/webserver/server.js
@@ -1,22 +1,29 @@
'use strict';
const Hapi = require('@hapi/hapi');
-const Good = require('@hapi/good');
const Inert = require('@hapi/inert');
const Vision = require('@hapi/vision');
const Blipp = require('blipp');
const HapiSwagger = require('hapi-swagger');
-const Package = require('../../../package');
-const routes = require('../../interfaces/routes');
const serviceLocator = require('../../infrastructure/config/service-locator')
const Jwt = require('@hapi/jwt');
+const strategy = require("../config/strategy")
+const Path = require("path");
+const refreshTokens = require("../routine/refreshTokens")
+const removeExpiredConfirmTokens = require("../routine/removeExpiredConfirmTokens")
+const HapiCors = require('hapi-cors');
const createServer = async () => {
-
// Create a server with a host and port
const server = Hapi.server({
- port: process.env.PORT || 3000
+ port: process.env.PORT || 3000,
+ routes:{
+ files: {
+ relativeTo: Path.join(__dirname.split("\\").slice(0,-3).join("/")+'/upload')
+ }
+ }
});
-
+ await server.register(Inert);
+ await server.register(Vision);
// Register vendors plugins
await server.register([
Blipp,
@@ -26,34 +33,20 @@ const createServer = async () => {
plugin: HapiSwagger,
options: {
info: {
- title: 'Test API Documentation',
- version: Package.version,
+ title: 'Solimbo',
+ version: '0.1'
},
}
},
{
- plugin: Good,
- options: {
- ops: {
- interval: 1000 * 60
- },
- reporters: {
- myConsoleReporter: [
- {
- module: '@hapi/good-squeeze',
- name: 'Squeeze',
- args: [{ ops: '*', log: '*', error: '*', response: '*' }]
- },
- {
- module: '@hapi/good-console'
- },
- 'stdout'
- ]
- }
- },
+ plugin: Jwt
},
{
- plugin: Jwt
+ plugin: HapiCors,
+ options: {
+ origins: ["http://"+process.env.FRONT_URL], // Specify the allowed origins
+ methods: ['GET', 'POST', 'PUT', 'DELETE'], // Specify the allowed HTTP methods
+ },
}
]);
// for (const route in routes) {
@@ -63,32 +56,20 @@ const createServer = async () => {
server.app.serviceLocator = serviceLocator;
-
- server.auth.strategy('jwt', 'jwt', {
- keys: process.env.SECRET_ENCODER, // replace with your secret key for signing and verifying JWTs
- verify: {
- aud: 'urn:audience:test',
- iss: 'urn:issuer:test',
- sub: false,
- nbf: true,
- exp: true,
- maxAgeSec: 14400, // 4 hours
- timeSkewSec: 15
- },
- validate: async (artifacts, request, h) => {
- const {userRepository} = server.app.serviceLocator
- const isValid = !!await userRepository.getByUser(artifacts.decoded.payload.value)
- return {
- isValid,
- };
- },
- });
+ server.auth.strategy('jwt', 'jwt', strategy(serviceLocator));
await server.register([
require('../../interfaces/routes/users'),
- require('../../interfaces/routes/spotify')
+ require('../../interfaces/routes/spotify'),
+ require('../../interfaces/routes/review'),
+ require('../../interfaces/routes/upload'),
+ require('../../interfaces/routes/friends'),
+ require('../../interfaces/routes/artist'),
+ require('../../interfaces/routes/oeuvre'),
+ require('../../interfaces/routes/comment')
]);
-
+ refreshTokens(serviceLocator)
+ removeExpiredConfirmTokens(serviceLocator)
return server;
};
diff --git a/lib/interfaces/controllers/ArtistController.js b/lib/interfaces/controllers/ArtistController.js
new file mode 100644
index 0000000..17c0765
--- /dev/null
+++ b/lib/interfaces/controllers/ArtistController.js
@@ -0,0 +1,34 @@
+'use strict';
+
+const getArtist = require('../../application/use_cases/artist/getArtist');
+const getArtistFollowers = require('../../application/use_cases/artist/getArtistFollowers');
+const handleError = require("./utils/handleError");
+
+module.exports = {
+
+ async get(request, handler){
+ const serviceLocator = request.server.app.serviceLocator;
+ const authorizationHeader = request.headers.authorization;
+ const [, token] = authorizationHeader.split(' ');
+ const {id} = request.params
+ try{
+ return handler.response(await getArtist(id,token, serviceLocator)).code(200)
+ }
+ catch (e){
+ return handleError(e)
+ }
+ },
+ async getFollowers(request, handler){
+ const serviceLocator = request.server.app.serviceLocator;
+ const authorizationHeader = request.headers.authorization;
+ const [, token] = authorizationHeader.split(' ');
+ const {id} = request.params
+ try{
+ return handler.response(await getArtistFollowers(id,token, serviceLocator)).code(200)
+ }
+ catch (e){
+ return handleError(e)
+ }
+ }
+
+}
diff --git a/lib/interfaces/controllers/CommentController.js b/lib/interfaces/controllers/CommentController.js
new file mode 100644
index 0000000..6c07a82
--- /dev/null
+++ b/lib/interfaces/controllers/CommentController.js
@@ -0,0 +1,61 @@
+const getComment = require("../../application/use_cases/comment/getComment");
+const deleteComment = require("../../application/use_cases/comment/deleteComment");
+const putComment = require("../../application/use_cases/comment/putComment");
+const likeComment = require("../../application/use_cases/comment/likeComment");
+const handleError = require("./utils/handleError");
+module.exports = {
+
+ async get(request,handler){
+ try{
+ // Context
+ const serviceLocator = request.server.app.serviceLocator; // a tous les repo
+ const authorizationHeader = request.headers.authorization;
+ const [, token ] = authorizationHeader.split(' ');
+ const {id} = request.params
+ const {page, pageSize, orderByLike} = request.query
+ return handler.response(await getComment(id,page, pageSize, orderByLike, token, serviceLocator)).code(200)
+ }catch(error){
+ return handleError(error)
+ }
+ },
+ async delete(request,handler){
+ try{
+ // Context
+ const serviceLocator = request.server.app.serviceLocator; // a tous les repo
+ const authorizationHeader = request.headers.authorization;
+ const [, token ] = authorizationHeader.split(' ');
+ const {id} = request.params
+
+ await deleteComment(id, token, serviceLocator)
+ return handler.response('').code(200)
+ }catch(error){
+ return handleError(error)
+ }
+ },
+ async put(request,handler){
+ try{
+ // Context
+ const serviceLocator = request.server.app.serviceLocator; // a tous les repo
+ const authorizationHeader = request.headers.authorization;
+ const [, token ] = authorizationHeader.split(' ');
+ const {id} = request.params
+ const {description} = request.payload
+ return handler.response(await putComment(id,description,token, serviceLocator)).code(200)
+ }catch(error){
+ return handleError(error)
+ }
+ },
+ async like(request,handler){
+ try{
+ // Context
+ const serviceLocator = request.server.app.serviceLocator; // a tous les repo
+ const authorizationHeader = request.headers.authorization;
+ const [, token ] = authorizationHeader.split(' ');
+ const {id} = request.params
+ await likeComment(id,token, serviceLocator)
+ return handler.response('').code(200)
+ }catch(error){
+ return handleError(error)
+ }
+ },
+}
\ No newline at end of file
diff --git a/lib/interfaces/controllers/FriendsController.js b/lib/interfaces/controllers/FriendsController.js
new file mode 100644
index 0000000..88b760d
--- /dev/null
+++ b/lib/interfaces/controllers/FriendsController.js
@@ -0,0 +1,95 @@
+'use strict';
+
+const followUser = require('../../application/use_cases/friend/followUser')
+const acceptRequestUser = require('../../application/use_cases/friend/acceptRequestUser')
+const unfollowUser = require('../../application/use_cases/friend/unfollowUser')
+const getListFriends = require('../../application/use_cases/friend/getListFriends')
+const getListFriendsRequest = require('../../application/use_cases/friend/getListFriendsRequest')
+const getProfilFriend = require('../../application/use_cases/friend/getProfilFriend')
+const handleError = require("./utils/handleError")
+
+module.exports = {
+
+ async followUser(request, handler){
+ const serviceLocator = request.server.app.serviceLocator;
+ const authorizationHeader = request.headers.authorization;
+ const [, token] = authorizationHeader.split(' ');
+ const {amiIdUtilisateur} = request.payload
+ try{
+ await followUser(token, amiIdUtilisateur, serviceLocator);
+ return handler.response("Demande d'ami envoyée / Ajout d'ami bien effectué").code(200)
+ }
+ catch (e){
+ return handleError(e)
+ }
+ },
+
+ async unfollowUser(request, handler){
+ const serviceLocator = request.server.app.serviceLocator;
+ const authorizationHeader = request.headers.authorization;
+ const [, token] = authorizationHeader.split(' ');
+ const {amiIdUtilisateur} = request.payload
+ try{
+ await unfollowUser(token, amiIdUtilisateur, serviceLocator);
+ return handler.response("Suppression d'un ami bien effectuée").code(200)
+ }
+ catch (e){
+ return handleError(e)
+ }
+ },
+
+ async acceptRequestUser(request, handler){
+ const serviceLocator = request.server.app.serviceLocator;
+ const authorizationHeader = request.headers.authorization;
+ const [, token] = authorizationHeader.split(' ');
+ const {amiIdUtilisateur} = request.payload;
+ try{
+ const user = await acceptRequestUser(token, amiIdUtilisateur, serviceLocator);
+ return handler.response("Demande d'ami bien acceptée").code(200)
+ }
+ catch (e){
+ return handleError(e)
+ }
+ },
+
+ async getListFriends(request, handler){
+ const serviceLocator = request.server.app.serviceLocator;
+ const authorizationHeader = request.headers.authorization;
+ const [, token] = authorizationHeader.split(' ');
+ try{
+ const friends = await getListFriends(token, serviceLocator);
+ return handler.response(friends).code(200)
+ }
+ catch (e){
+ return handleError(e)
+ }
+ },
+
+ async getListFriendsRequest(request, handler){
+ const serviceLocator = request.server.app.serviceLocator;
+ const authorizationHeader = request.headers.authorization;
+ const [, token] = authorizationHeader.split(' ');
+ try{
+ const requests = await getListFriendsRequest(token, serviceLocator);
+ return handler.response(requests).code(200)
+ }
+ catch (e){
+ return handleError(e)
+ }
+ },
+
+ async getProfilFriend(request, handler){
+ const serviceLocator = request.server.app.serviceLocator;
+ const authorizationHeader = request.headers.authorization;
+ const [, token] = authorizationHeader.split(' ');
+ const {amiIdUtilisateur} = request.payload
+ try{
+ const user = await getProfilFriend(token, amiIdUtilisateur, serviceLocator);
+ return handler.response(user).code(200)
+ }
+ catch (e){
+ return handleError(e)
+ }
+ }
+
+}
diff --git a/lib/interfaces/controllers/OeuvreController.js b/lib/interfaces/controllers/OeuvreController.js
new file mode 100644
index 0000000..7cde952
--- /dev/null
+++ b/lib/interfaces/controllers/OeuvreController.js
@@ -0,0 +1,37 @@
+'use strict';
+
+const likeOeuvre = require('../../application/use_cases/oeuvre/likeOeuvre');
+const getOeuvre = require('../../application/use_cases/oeuvre/getOeuvre');
+const handleError = require("./utils/handleError");
+
+
+module.exports = {
+
+ async like(request, handler){
+ const serviceLocator = request.server.app.serviceLocator;
+ const authorizationHeader = request.headers.authorization;
+ const [, token] = authorizationHeader.split(' ');
+ const {id,type} = request.params
+ try{
+ await likeOeuvre(token,id,type, serviceLocator)
+ return handler.response("").code(200)
+ }
+ catch (e){
+ return handleError(e)
+ }
+ },
+ async get(request, handler){
+ const serviceLocator = request.server.app.serviceLocator;
+ const authorizationHeader = request.headers.authorization;
+ const [, token] = authorizationHeader.split(' ');
+ const {id} = request.params
+ try{
+ return handler.response(await getOeuvre(id,token, serviceLocator)).code(200)
+ }
+ catch (e){
+ return handleError(e)
+ }
+ }
+
+
+}
diff --git a/lib/interfaces/controllers/ReviewController.js b/lib/interfaces/controllers/ReviewController.js
new file mode 100644
index 0000000..9ef0644
--- /dev/null
+++ b/lib/interfaces/controllers/ReviewController.js
@@ -0,0 +1,242 @@
+const putReview = require("../../application/use_cases/review/putReview");
+const deleteReview = require("../../application/use_cases/review/deleteReview");
+const getReview = require("../../application/use_cases/review/getReview");
+const getReviews = require("../../application/use_cases/review/getReviews");
+const likeReview = require("../../application/use_cases/review/likeReview");
+const getReviewLikes = require("../../application/use_cases/review/getReviewLikes");
+const getUserReviews = require("../../application/use_cases/review/getUserReviews");
+const getOeuvreReviews = require("../../application/use_cases/review/getOeuvreReviews");
+const getArtistReviews = require("../../application/use_cases/review/getArtistReviews");
+const putComment = require("../../application/use_cases/review/putComment");
+const getCountOeuvreReviews = require("../../application/use_cases/review/getCountOeuvreReviews");
+const handleError = require("./utils/handleError");
+
+module.exports = {
+ async putReview(request, handler) {
+ try {
+ // Context
+ const serviceLocator = request.server.app.serviceLocator; // a tous les repo
+ const authorizationHeader = request.headers.authorization;
+ const [, token] = authorizationHeader.split(" ");
+ const { idOeuvre, note, description, type } = request.payload;
+
+ return handler
+ .response(
+ await putReview(
+ idOeuvre,
+ token,
+ description,
+ note,
+ type,
+ serviceLocator
+ )
+ )
+ .code(200);
+ } catch (error) {
+ return handleError(error);
+ }
+ },
+ async deleteReview(request, handler) {
+ try {
+ // Context
+ const serviceLocator = request.server.app.serviceLocator;
+ const authorizationHeader = request.headers.authorization;
+ const [, token] = authorizationHeader.split(" ");
+ const { idReview } = request.payload;
+ await deleteReview(idReview, token, serviceLocator);
+ return handler.response("").code(200);
+ } catch (error) {
+ return handleError(error);
+ }
+ },
+ async getReview(request, handler) {
+ try {
+ // Context
+ const serviceLocator = request.server.app.serviceLocator; // a tous les repo
+ const { id } = request.params;
+ const { page, pageSize, orderByLike } = request.query;
+ const authorizationHeader = request.headers.authorization;
+ const token = authorizationHeader?.split(" ")[1];
+ return handler
+ .response(
+ await getReview(
+ id,
+ token,
+ page,
+ pageSize,
+ orderByLike,
+ serviceLocator
+ )
+ )
+ .code(200);
+ } catch (error) {
+ return handleError(error);
+ }
+ },
+ async getReviews(request, handler) {
+ try {
+ // Context
+ const serviceLocator = request.server.app.serviceLocator; // a tous les repo
+ const { page, pageSize, orderByLike, friendsOnly } = request.query;
+ const authorizationHeader = request.headers.authorization;
+ const token = authorizationHeader?.split(" ")[1];
+ return handler
+ .response(
+ await getReviews(
+ page,
+ pageSize,
+ orderByLike,
+ friendsOnly,
+ token,
+ serviceLocator
+ )
+ )
+ .code(200);
+ } catch (error) {
+ return handleError(error);
+ }
+ },
+ async likeReview(request, handler) {
+ try {
+ // Context
+ const serviceLocator = request.server.app.serviceLocator; // a tous les repo
+ const { id } = request.params;
+ const authorizationHeader = request.headers.authorization;
+ const token = authorizationHeader?.split(" ")[1];
+ await likeReview(id, token, serviceLocator);
+ return handler.response("").code(200);
+ } catch (error) {
+ return handleError(error);
+ }
+ },
+ async getLikes(request, handler) {
+ try {
+ // Context
+ const serviceLocator = request.server.app.serviceLocator; // a tous les repo
+ const authorizationHeader = request.headers.authorization;
+ const token = authorizationHeader?.split(" ")[1];
+ const { id } = request.params;
+ const { page, pageSize } = request.query;
+ return handler
+ .response(
+ await getReviewLikes(id, token, page, pageSize, serviceLocator)
+ )
+ .code(200);
+ } catch (error) {
+ return handleError(error);
+ }
+ },
+ async getUserReviews(request, handler) {
+ try {
+ // Context
+ const serviceLocator = request.server.app.serviceLocator; // a tous les repo
+ const authorizationHeader = request.headers.authorization;
+ const token = authorizationHeader?.split(" ")[1];
+ const { id } = request.params;
+ const { page, pageSize, orderByLike } = request.query;
+ return handler
+ .response(
+ await getUserReviews(
+ id,
+ token,
+ page,
+ pageSize,
+ orderByLike,
+ serviceLocator
+ )
+ )
+ .code(200);
+ } catch (error) {
+ return handleError(error);
+ }
+ },
+ async getOeuvreReviews(request, handler) {
+ try {
+ // Context
+ const serviceLocator = request.server.app.serviceLocator; // a tous les repo
+ const authorizationHeader = request.headers.authorization;
+ const token = authorizationHeader?.split(" ")[1];
+ const { id } = request.params;
+ const { page, pageSize, orderByLike } = request.query;
+ const response = {
+ data: await getOeuvreReviews(
+ id,
+ token,
+ page,
+ pageSize,
+ orderByLike,
+ serviceLocator
+ ),
+ count: await getCountOeuvreReviews(id, token, serviceLocator),
+ };
+ return handler.response(response).code(200);
+ } catch (error) {
+ return handleError(error);
+ }
+ },
+ async getArtistReviews(request, handler) {
+ try {
+ // Context
+ const serviceLocator = request.server.app.serviceLocator; // a tous les repo
+ const authorizationHeader = request.headers.authorization;
+ const token = authorizationHeader?.split(" ")[1];
+ const { id } = request.params;
+ const { page, pageSize, orderByLike, friendsOnly } = request.query;
+ return handler
+ .response(
+ await getArtistReviews(
+ id,
+ token,
+ page,
+ pageSize,
+ orderByLike,
+ friendsOnly,
+ serviceLocator
+ )
+ )
+ .code(200);
+ } catch (error) {
+ return handleError(error);
+ }
+ },
+
+ async putComment(request, handler) {
+ try {
+ const serviceLocator = request.server.app.serviceLocator;
+ const authorizationHeader = request.headers.authorization;
+ const token = authorizationHeader?.split(" ")[1];
+ const { id } = request.params;
+ const { description } = request.payload;
+ return handler
+ .response(await putComment(token, id, description, serviceLocator))
+ .code(200);
+ } catch (error) {
+ return handleError(error);
+ }
+ },
+ async getOeuvreReviews(request, handler) {
+ try {
+ // Context
+ const serviceLocator = request.server.app.serviceLocator; // a tous les repo
+ const authorizationHeader = request.headers.authorization;
+ const token = authorizationHeader?.split(" ")[1];
+ const { id } = request.params;
+ const { page, pageSize, orderByLike, friendsOnly } = request.query;
+ const response = {
+ data: await getOeuvreReviews(
+ id,
+ token,
+ page,
+ pageSize,
+ orderByLike,
+ friendsOnly,
+ serviceLocator
+ ),
+ count: await getCountOeuvreReviews(id, token, serviceLocator),
+ };
+ return handler.response(response).code(200);
+ } catch (error) {
+ return handleError(error);
+ }
+ },
+};
diff --git a/lib/interfaces/controllers/SpotifyController.js b/lib/interfaces/controllers/SpotifyController.js
index b5d08fd..dcbebff 100644
--- a/lib/interfaces/controllers/SpotifyController.js
+++ b/lib/interfaces/controllers/SpotifyController.js
@@ -1,18 +1,80 @@
const search = require("../../application/use_cases/spotify/Search");
+const getAlbum = require("../../application/use_cases/spotify/getAlbum");
+const fetchArtist = require("../../application/use_cases/spotify/FetchArtist");
+const getTrack = require("../../application/use_cases/spotify/getTrack");
+const getSearchFilters = require("../../application/use_cases/spotify/getSearchFilters");
const handleError = require("./utils/handleError");
+const fetchArtistSongs = require("../../application/use_cases/spotify/FetchArtistSongs");
+
+
module.exports = {
async search(request,handler){
+ try{
+ // Context
+ const serviceLocator = request.server.app.serviceLocator; // a tous les repo
+ // Input
+ // spotify_filter = type de l'API Spotify
+ let { query, spotify_filter, limit} = request.query
+ const searchResult = await search(query,spotify_filter, limit, serviceLocator)
+ return handler.response(searchResult).code(200)
+ }catch(error){
+ return handleError(error)
+ }
+ },
+ async getSearchFilters(request,handler){
+ try{
+
+ const searchFilters = await getSearchFilters()
+ return handler.response(searchFilters).code(200)
+ }catch(error){
+ return handleError(error)
+ }
+ },
+ async getAlbums(request,handler){
try{
// Context
const serviceLocator = request.server.app.serviceLocator;
// Input
+ let {id} = request.query
+ const result = await getAlbum(id, serviceLocator)
+ return handler.response(result).code(200)
+ }catch(error){
+ return handleError(error)
+ }
+ },
- let { query, spotify_filter, limit, allow_user} = request.query
- const searchResult = await search(query,spotify_filter, limit,allow_user, serviceLocator)
- return handler.response(searchResult).code(200)
+ async getTracks(request,handler){
+ try{
+ // Context
+ const serviceLocator = request.server.app.serviceLocator;
+ // Input
+ let {id} = request.query
+ const result = await getTrack(id, serviceLocator)
+ return handler.response(result).code(200)
+ }catch(error){
+ return handleError(error)
+ }
+ },
+
+ async fetchArtist(request,handler){
+ try {
+ const serviceLocator = request.server.app.serviceLocator;
+ const id = request.query.query
+ const fetchArtistResult = await fetchArtist(id, serviceLocator)
+ return handler.response(fetchArtistResult).code(200) // tout s est bien passe
+ }catch(error){
+ return handleError(error)
+ }
+ },
+ async fetchArtistSongs(request,handler){
+ try {
+ const serviceLocator = request.server.app.serviceLocator;
+ let {id, filter, limit} = request.query
+ const fetchArtistSongsResult = await fetchArtistSongs(id, filter, limit, serviceLocator)
+ return handler.response(fetchArtistSongsResult).code(200)
}catch(error){
return handleError(error)
}
- }
+ },
}
\ No newline at end of file
diff --git a/lib/interfaces/controllers/UploadController.js b/lib/interfaces/controllers/UploadController.js
new file mode 100644
index 0000000..198e41e
--- /dev/null
+++ b/lib/interfaces/controllers/UploadController.js
@@ -0,0 +1,8 @@
+const Path = require('path');
+module.exports = {
+ async getImage(request,handler){
+ const {filename} = request.params
+
+ return handler.file(filename)
+ }
+}
\ No newline at end of file
diff --git a/lib/interfaces/controllers/UsersController.js b/lib/interfaces/controllers/UsersController.js
index e572d16..158a13d 100644
--- a/lib/interfaces/controllers/UsersController.js
+++ b/lib/interfaces/controllers/UsersController.js
@@ -1,37 +1,249 @@
-'use strict';
+"use strict";
+
+const CreateUser = require("../../application/use_cases/user/CreateUser");
+const AuthWithSpotify = require("../../application/use_cases/user/AuthWithSpotify");
+const CompleteAccount = require("../../application/use_cases/user/CompleteAccount");
+const GetAccessToken = require("../../application/use_cases/security/GetAccessToken");
+const handleError = require("./utils/handleError");
+const uploadPreview = require("../../application/use_cases/user/uploadPreview");
+const getUserByPseudo = require("../../application/use_cases/user/getUserByPseudo");
+const getUserByConfirmToken = require("../../application/use_cases/user/getUserByConfirmToken");
+const sendResetEmail = require("../../application/use_cases/user/sendResetEmail");
+const resetPassword = require("../../application/use_cases/user/resetPassword");
+const changePrivateStatus = require("../../application/use_cases/user/changePrivateStatus");
+const refreshToken = require("../../application/use_cases/spotify/RefreshToken");
+const throwStatusCode = require("../../application/use_cases/utils/throwStatusCode");
+const follow = require("../../application/use_cases/user/follow");
+const oeuvreFav = require("../../application/use_cases/user/oeuvreFav");
+const getOeuvresFav = require("../../application/use_cases/user/getOeuvresFav");
+const getPage = require("../../application/use_cases/user/getPage");
+const modifyProfile = require("../../application/use_cases/user/modifyProfile");
-const CreateUser = require('../../application/use_cases/user/CreateUser');
-const GetAccessToken = require('../../application/use_cases/security/GetAccessToken');
-const handleError = require("./utils/handleError")
module.exports = {
+ async confirmUser(request, handler) {
+ try {
+ // Context
+ const serviceLocator = request.server.app.serviceLocator;
+ // Input
+
+ let { pseudo, photo, alias, bio, confirmToken } = request.payload;
+ return handler
+ .response(
+ await CompleteAccount(
+ pseudo,
+ alias,
+ bio,
+ photo,
+ confirmToken,
+ serviceLocator
+ )
+ )
+ .code(200);
+ } catch (error) {
+ return handleError(error);
+ }
+ },
- async createUser(request,handler) {
- try{
- // Context
- const serviceLocator = request.server.app.serviceLocator;
- // Input
+ async signIn(request, handler) {
+ console.log("tesssssssssssssssssst");
+ const serviceLocator = request.server.app.serviceLocator;
+ const { email, password } = request.payload;
+ try {
+ return handler
+ .response(await GetAccessToken(email, password, serviceLocator))
+ .code(200);
+ } catch (error) {
+ return handleError(error);
+ }
+ },
+ async uploadPreviewProfile(request, handler) {
+ const serviceLocator = request.server.app.serviceLocator;
+ const authorizationHeader = request.headers.authorization;
+ const [, token] = authorizationHeader.split(" ");
+ const { file } = request.payload;
+ try {
+ return handler
+ .response({
+ path: `${request.server.info.uri}/${await uploadPreview(
+ file,
+ token,
+ serviceLocator
+ )}`,
+ })
+ .code(200);
+ } catch (e) {
+ return handleError(e);
+ }
+ },
+ async authWithSpotify(request, handler) {
+ const serviceLocator = request.server.app.serviceLocator;
+ const { spotify_code, callback } = request.payload;
+ try {
+ const returnValue = await AuthWithSpotify(
+ spotify_code,
+ callback,
+ serviceLocator
+ );
+ if (returnValue.idUtilisateur) {
+ refreshToken(returnValue.idUtilisateur, false, serviceLocator);
+ delete returnValue.idUtilisateur;
+ }
+ return handler.response(returnValue).code(200);
+ } catch (e) {
+ return handleError(e);
+ }
+ },
+ async createUser(request, handler) {
+ const serviceLocator = request.server.app.serviceLocator;
+ const { email, password } = request.payload;
+ try {
+ console.log(email, password);
+ const user = await CreateUser(email, password, serviceLocator);
- let { pseudo, email, alias, bio, password,spotifyToken } = request.payload
- await CreateUser(pseudo, email, alias, bio, password,spotifyToken, serviceLocator);
- return handler.response('Votre compte a bien été crée').code(200)
- }catch(error){
- return handleError(error)
- }
- },
+ return handler.response("compte créé").code(200);
+ } catch (e) {
+ return handleError(e);
+ }
+ },
+ async isUser(request, handler) {
+ const serviceLocator = request.server.app.serviceLocator;
+ const { pseudo } = request.query;
+ try {
+ const user = await getUserByPseudo(pseudo, serviceLocator);
+ return handler.response({ isUser: !!user }).code(200);
+ } catch (e) {
+ return handleError(e);
+ }
+ },
+ async getUserByConfirmToken(request, handler) {
+ const serviceLocator = request.server.app.serviceLocator;
+ const { confirmToken } = request.query;
+ try {
+ const user = await getUserByConfirmToken(confirmToken, serviceLocator);
+ if (!user) throwStatusCode(403, "no user");
+ return handler.response(user).code(200);
+ } catch (e) {
+ return handleError(e);
+ }
+ },
+ async sendResetEmail(request, handler) {
+ const serviceLocator = request.server.app.serviceLocator;
+ const { email } = request.payload;
+ try {
+ await sendResetEmail(email, serviceLocator);
+ return handler.response("un email a été envoyé").code(200);
+ } catch (e) {
+ return handleError(e);
+ }
+ },
+ async resetPassword(request, handler) {
+ const serviceLocator = request.server.app.serviceLocator;
+ const { password, resetToken } = request.payload;
+ try {
+ await resetPassword(password, resetToken, serviceLocator);
+ return handler.response("un email a été envoyé").code(200);
+ } catch (e) {
+ return handleError(e);
+ }
+ },
+ async follow(request, handler) {
+ const serviceLocator = request.server.app.serviceLocator;
+ const authorizationHeader = request.headers.authorization;
+ const [, token] = authorizationHeader.split(" ");
+ const { artistId } = request.payload;
+ try {
+ const returnValue = (await follow(token, artistId, serviceLocator))
+ ? "artiste suivi"
+ : "vous avez arrêté de suivre l'artiste";
+ return handler.response(returnValue).code(200);
+ } catch (error) {
+ return handleError(error);
+ }
+ },
+ async changePrivateStatus(request, handler) {
+ const serviceLocator = request.server.app.serviceLocator;
+ const authorizationHeader = request.headers.authorization;
+ const [, token] = authorizationHeader.split(" ");
+ try {
+ await changePrivateStatus(token, serviceLocator);
+ return handler
+ .response("Le statut du compte a bien été mis à jour")
+ .code(200);
+ } catch (e) {
+ return handleError(e);
+ }
+ },
+ async oeuvreFav(request, handler) {
+ const serviceLocator = request.server.app.serviceLocator;
+ const authorizationHeader = request.headers.authorization;
+ const [, token] = authorizationHeader.split(" ");
+ const { idOeuvre, type } = request.payload;
+ console.log(request.payload);
+ try {
+ // await oeuvreFav(idOeuvre,serviceLocator);
+ const returnValue = (await oeuvreFav(
+ token,
+ idOeuvre,
+ type,
+ serviceLocator
+ ))
+ ? "L'oeuvre a été rajoutée en favori"
+ : "L'oeuvre a été retirée de vos favori";
+ return handler.response(returnValue).code(200);
+ } catch (e) {
+ return handleError(e);
+ }
+ },
- async signIn(request,handler){
+ async getOeuvresFav(request, handler) {
+ const serviceLocator = request.server.app.serviceLocator;
+ const authorizationHeader = request.headers.authorization;
+ const [, token] = authorizationHeader.split(" ");
+ try {
+ const arrayOeuvresFav = await getOeuvresFav(token, serviceLocator);
- const serviceLocator = request.server.app.serviceLocator;
- const {email, password} = request.payload
- try{
- return handler
- .response({
- email : email,
- token: await GetAccessToken(email,password,serviceLocator)
- })
- }
- catch (error){
- return handleError(error)
- }
+ return handler.response(arrayOeuvresFav).code(200);
+ } catch (e) {
+ return handleError(e);
+ }
+ },
+ async getPage(request, handler) {
+ try {
+ const serviceLocator = request.server.app.serviceLocator;
+ const authorizationHeader = request.headers.authorization;
+ const [, token] = authorizationHeader.split(" ");
+ const { page, pageSize, orderByLike } = request.query;
+ const { id } = request.params;
+ return handler
+ .response(
+ await getPage(id, page, pageSize, orderByLike, token, serviceLocator)
+ )
+ .code(200);
+ } catch (e) {
+ return handleError(e);
+ }
+ },
+ async modify(request, handler) {
+ try {
+ const serviceLocator = request.server.app.serviceLocator;
+ const authorizationHeader = request.headers.authorization;
+ const [, token] = authorizationHeader.split(" ");
+ const { photo, pseudo, bio, alias, isPrivate } = request.payload;
+ return handler
+ .response(
+ await modifyProfile(
+ photo,
+ pseudo,
+ bio,
+ alias,
+ isPrivate,
+ token,
+ serviceLocator
+ )
+ )
+ .code(200);
+ } catch (e) {
+ return handleError(e);
}
+ },
};
diff --git a/lib/interfaces/controllers/utils/handleError.js b/lib/interfaces/controllers/utils/handleError.js
index 2b19f3d..caa37d7 100644
--- a/lib/interfaces/controllers/utils/handleError.js
+++ b/lib/interfaces/controllers/utils/handleError.js
@@ -1,7 +1,7 @@
const Boom = require("@hapi/boom")
module.exports = (error) => {
- const statusCode = error.code ? error.code : 500
+ const statusCode = error?.code ? error.code : 500
console.log(error)
return Boom.boomify(error, {statusCode: statusCode})
}
\ No newline at end of file
diff --git a/lib/interfaces/routes/artist.js b/lib/interfaces/routes/artist.js
new file mode 100644
index 0000000..7d71258
--- /dev/null
+++ b/lib/interfaces/routes/artist.js
@@ -0,0 +1,66 @@
+const ArtistController = require("../controllers/ArtistController");
+const {
+ getArtist
+} = require("../../domain/entity/ArtistEntity");
+module.exports = {
+ name: 'artist',
+ version: '1.0.0',
+ register: async (server) => {
+ server.route([
+ {
+ method: 'GET',
+ path: '/artist/{id}',
+ handler: ArtistController.get,
+ options: {
+ auth: 'jwt',
+ description: 'get artist information',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description : 'Success'},
+ 204: {description : 'No content'},
+ 401: {description : 'Unauthorized'},
+ 403: {description : 'forbidden'},
+ 404: {description : 'Ressource not found'},
+ 500: {description : 'Internal server error'},
+ 502: {description : 'bad gateway'},
+ 503: {description : 'Service unavailable'},
+ }
+ }
+ },
+ validate: {
+ params: getArtist
+ }
+ },
+ },
+ {
+ method: 'GET',
+ path: '/artist/{id}/followers',
+ handler: ArtistController.getFollowers,
+ options: {
+ auth: 'jwt',
+ description: 'get artist followers',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description : 'Success'},
+ 204: {description : 'No content'},
+ 401: {description : 'Unauthorized'},
+ 403: {description : 'forbidden'},
+ 404: {description : 'Ressource not found'},
+ 500: {description : 'Internal server error'},
+ 502: {description : 'bad gateway'},
+ 503: {description : 'Service unavailable'},
+ }
+ }
+ },
+ validate: {
+ params: getArtist
+ }
+ },
+ },
+ ]);
+ }
+};
\ No newline at end of file
diff --git a/lib/interfaces/routes/comment.js b/lib/interfaces/routes/comment.js
new file mode 100644
index 0000000..ba103ec
--- /dev/null
+++ b/lib/interfaces/routes/comment.js
@@ -0,0 +1,126 @@
+const CommentController = require("../controllers/CommentController");
+const {
+ getCommentParams,
+ deleteCommentParams,
+ likeCommentParams,
+ putCommentPayload,
+ putCommentParams,
+ getCommentQuery
+} = require("../../domain/entity/CommentEntity");
+module.exports = {
+ name: 'comment',
+ version: '1.0.0',
+ register: async (server) => {
+ server.route([
+ {
+ method: 'GET',
+ path: '/comment/{id}',
+ handler: CommentController.get,
+ options: {
+ description: 'get a comment',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description : 'Success'},
+ 204: {description : 'No content'},
+ 401: {description : 'Unauthorized'},
+ 403: {description : 'forbidden'},
+ 404: {description : 'Ressource not found'},
+ 500: {description : 'Internal server error'},
+ 502: {description : 'bad gateway'},
+ 503: {description : 'Service unavailable'},
+ }
+ }
+ },
+ validate: {
+ params: getCommentParams,
+ query: getCommentQuery
+ }
+ },
+ },
+ {
+ method: 'DELETE',
+ path: '/comment/{id}',
+ handler: CommentController.delete,
+ options: {
+ auth: 'jwt',
+ description: 'delete a comment',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description : 'Success'},
+ 204: {description : 'No content'},
+ 401: {description : 'Unauthorized'},
+ 403: {description : 'forbidden'},
+ 404: {description : 'Ressource not found'},
+ 500: {description : 'Internal server error'},
+ 502: {description : 'bad gateway'},
+ 503: {description : 'Service unavailable'},
+ }
+ }
+ },
+ validate: {
+ params: deleteCommentParams
+ }
+ },
+ },
+ {
+ method: 'POST',
+ path: '/comment/{id}/like',
+ handler: CommentController.like,
+ options: {
+ auth: 'jwt',
+ description: 'like a comment',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description: 'Success'},
+ 204: {description: 'No content'},
+ 401: {description: 'Unauthorized'},
+ 403: {description: 'forbidden'},
+ 404: {description: 'Ressource not found'},
+ 500: {description: 'Internal server error'},
+ 502: {description: 'bad gateway'},
+ 503: {description: 'Service unavailable'},
+ }
+ }
+ },
+ validate: {
+ params: likeCommentParams,
+ }
+ }
+ },
+ {
+ method: 'PUT',
+ path: '/comment/{id}',
+ handler: CommentController.put,
+ options: {
+ auth: 'jwt',
+ description: 'get review list',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description: 'Success'},
+ 204: {description: 'No content'},
+ 401: {description: 'Unauthorized'},
+ 403: {description: 'forbidden'},
+ 404: {description: 'Ressource not found'},
+ 500: {description: 'Internal server error'},
+ 502: {description: 'bad gateway'},
+ 503: {description: 'Service unavailable'},
+ }
+ }
+ },
+ validate: {
+ payload: putCommentPayload,
+ params: putCommentParams,
+ }
+ }
+ },
+ ])
+ }
+};
\ No newline at end of file
diff --git a/lib/interfaces/routes/friends.js b/lib/interfaces/routes/friends.js
new file mode 100644
index 0000000..b54d548
--- /dev/null
+++ b/lib/interfaces/routes/friends.js
@@ -0,0 +1,155 @@
+'use strict';
+
+const FriendsController = require('../controllers/FriendsController')
+const Joi = require('joi')
+
+module.exports = {
+ name: 'amis',
+ version: '1.0.0',
+ register: async (server) => {
+
+ server.route([
+ {
+ method: 'POST',
+ path: '/amis/follow',
+ handler: FriendsController.followUser,
+ options: {
+ description: 'Follow a user',
+ tags: ['api'],
+ auth: 'jwt',
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description : 'Success'},
+ 403: {description : 'forbidden'},
+ 500: {description : 'Internal server error'},
+ 502: {description : 'bad gateway'},
+ }
+ }
+ },
+ validate: {
+ payload: Joi.object().keys({
+ amiIdUtilisateur: Joi.number().required(),
+ })
+ }
+ },
+ },
+ {
+ method: 'POST',
+ path: '/amis/unfollow',
+ handler: FriendsController.unfollowUser,
+ options: {
+ description: 'Unfollow a user',
+ tags: ['api'],
+ auth: 'jwt',
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description : 'Success'},
+ 403: {description : 'forbidden'},
+ 500: {description : 'Internal server error'},
+ 502: {description : 'bad gateway'},
+ }
+ }
+ },
+ validate: {
+ payload: Joi.object().keys({
+ amiIdUtilisateur: Joi.number().required(),
+ })
+ }
+ },
+ },
+ {
+ method: 'POST',
+ path: '/amis/accept',
+ handler: FriendsController.acceptRequestUser,
+ options: {
+ description: 'Accept a friend request',
+ tags: ['api'],
+ auth: 'jwt',
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description : 'Success'},
+ 403: {description : 'forbidden'},
+ 500: {description : 'Internal server error'},
+ 502: {description : 'bad gateway'},
+ }
+ }
+ },
+ validate: {
+ payload: Joi.object().keys({
+ amiIdUtilisateur: Joi.number().required(),
+ })
+ }
+ },
+ },
+ {
+ method: 'GET',
+ path: '/amis/request',
+ handler: FriendsController.getListFriendsRequest,
+ options: {
+ description: 'Get a user\'s request friends list',
+ tags: ['api'],
+ auth: 'jwt',
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description : 'Success'},
+ 403: {description : 'forbidden'},
+ 500: {description : 'Internal server error'},
+ 502: {description : 'bad gateway'},
+ }
+ }
+ },
+ },
+ },
+ {
+ method: 'GET',
+ path: '/amis/list',
+ handler: FriendsController.getListFriends,
+ options: {
+ description: 'Get a user\'s friends list',
+ tags: ['api'],
+ auth: 'jwt',
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description : 'Success'},
+ 403: {description : 'forbidden'},
+ 500: {description : 'Internal server error'},
+ 502: {description : 'bad gateway'},
+ }
+ }
+ },
+ }
+ },
+ {
+ method: 'POST',
+ path: '/amis/profil',
+ handler: FriendsController.getProfilFriend,
+ options: {
+ description: 'Get a friend profil',
+ tags: ['api'],
+ auth: 'jwt',
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description : 'Success'},
+ 403: {description : 'forbidden'},
+ 500: {description : 'Internal server error'},
+ 502: {description : 'bad gateway'},
+ }
+ }
+ },
+ validate: {
+ payload: Joi.object().keys({
+ amiIdUtilisateur: Joi.number().required(),
+ })
+ }
+ }
+ },
+
+ ]);
+ }
+};
\ No newline at end of file
diff --git a/lib/interfaces/routes/oeuvre.js b/lib/interfaces/routes/oeuvre.js
new file mode 100644
index 0000000..ff39926
--- /dev/null
+++ b/lib/interfaces/routes/oeuvre.js
@@ -0,0 +1,68 @@
+const OeuvreController = require("../controllers/OeuvreController.js");
+
+const {
+ likeOeuvre,
+ getOeuvre
+} = require("../../domain/entity/OeuvreEntity.js");
+module.exports = {
+ name: 'oeuvre',
+ version: '1.0.0',
+ register: async (server) => {
+ server.route([
+ {
+ method: 'POST',
+ path: '/oeuvre/{type}/{id}/like',
+ handler: OeuvreController.like,
+ options: {
+ auth: 'jwt',
+ description: 'like/unlike an oeuvre',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description : 'Success'},
+ 204: {description : 'No content'},
+ 401: {description : 'Unauthorized'},
+ 403: {description : 'forbidden'},
+ 404: {description : 'Ressource not found'},
+ 500: {description : 'Internal server error'},
+ 502: {description : 'bad gateway'},
+ 503: {description : 'Service unavailable'},
+ }
+ }
+ },
+ validate: {
+ params: likeOeuvre
+ }
+ },
+ },
+ {
+ method: 'GET',
+ path: '/oeuvre/{id}',
+ handler: OeuvreController.get,
+ options: {
+ auth: 'jwt',
+ description: 'get oeuvre information',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description : 'Success'},
+ 204: {description : 'No content'},
+ 401: {description : 'Unauthorized'},
+ 403: {description : 'forbidden'},
+ 404: {description : 'Ressource not found'},
+ 500: {description : 'Internal server error'},
+ 502: {description : 'bad gateway'},
+ 503: {description : 'Service unavailable'},
+ }
+ }
+ },
+ validate: {
+ params: getOeuvre
+ }
+ },
+ }
+ ]);
+ }
+};
\ No newline at end of file
diff --git a/lib/interfaces/routes/review.js b/lib/interfaces/routes/review.js
new file mode 100644
index 0000000..aa0341a
--- /dev/null
+++ b/lib/interfaces/routes/review.js
@@ -0,0 +1,296 @@
+const ReviewController = require("../controllers/ReviewController");
+const {
+ putReview,
+ deleteReview,
+ getReviews,
+ getReviewParams,
+ getReviewQuery,
+ likeReviewParams,
+ likeReviewQuery,
+ userReviewParams,
+ putCommentParams,
+ putCommentPayload,
+ userReviewQuery,
+ oeuvreReviewParams,
+ oeuvreReviewQuery,
+ artistReviewParams,
+ artistReviewQuery,
+} = require("../../domain/entity/ReviewEntity");
+module.exports = {
+ name: "review",
+ version: "1.0.0",
+ register: async (server) => {
+ server.route([
+ {
+ method: "PUT",
+ path: "/review",
+ handler: ReviewController.putReview,
+ options: {
+ auth: "jwt",
+ description: "create a review",
+ tags: ["api"],
+ plugins: {
+ "hapi-swagger": {
+ responses: {
+ 200: { description: "Success" },
+ 204: { description: "No content" },
+ 401: { description: "Unauthorized" },
+ 403: { description: "forbidden" },
+ 404: { description: "Ressource not found" },
+ 500: { description: "Internal server error" },
+ 502: { description: "bad gateway" },
+ 503: { description: "Service unavailable" },
+ },
+ },
+ },
+ validate: {
+ payload: putReview,
+ },
+ },
+ },
+ {
+ method: "DELETE",
+ path: "/review",
+ handler: ReviewController.deleteReview,
+ options: {
+ auth: "jwt",
+ description: "delete a review",
+ tags: ["api"],
+ plugins: {
+ "hapi-swagger": {
+ responses: {
+ 200: { description: "Success" },
+ 204: { description: "No content" },
+ 401: { description: "Unauthorized" },
+ 403: { description: "forbidden" },
+ 404: { description: "Ressource not found" },
+ 500: { description: "Internal server error" },
+ 502: { description: "bad gateway" },
+ 503: { description: "Service unavailable" },
+ },
+ },
+ },
+ validate: {
+ payload: deleteReview,
+ },
+ },
+ },
+ {
+ method: "GET",
+ path: "/review/{id}",
+ handler: ReviewController.getReview,
+ options: {
+ description: "get a review",
+ tags: ["api"],
+ plugins: {
+ "hapi-swagger": {
+ responses: {
+ 200: { description: "Success" },
+ 204: { description: "No content" },
+ 401: { description: "Unauthorized" },
+ 403: { description: "forbidden" },
+ 404: { description: "Ressource not found" },
+ 500: { description: "Internal server error" },
+ 502: { description: "bad gateway" },
+ 503: { description: "Service unavailable" },
+ },
+ },
+ },
+ validate: {
+ params: getReviewParams,
+ query: getReviewQuery,
+ },
+ },
+ },
+ {
+ method: "GET",
+ path: "/reviews",
+ handler: ReviewController.getReviews,
+ options: {
+ description: "get review list",
+ tags: ["api"],
+ plugins: {
+ "hapi-swagger": {
+ responses: {
+ 200: { description: "Success" },
+ 204: { description: "No content" },
+ 401: { description: "Unauthorized" },
+ 403: { description: "forbidden" },
+ 404: { description: "Ressource not found" },
+ 500: { description: "Internal server error" },
+ 502: { description: "bad gateway" },
+ 503: { description: "Service unavailable" },
+ },
+ },
+ },
+ validate: {
+ query: getReviews,
+ },
+ },
+ },
+ {
+ method: "POST",
+ path: "/review/{id}/like",
+ handler: ReviewController.likeReview,
+ options: {
+ auth: "jwt",
+ description: "like a review",
+ tags: ["api"],
+ plugins: {
+ "hapi-swagger": {
+ responses: {
+ 200: { description: "Success" },
+ 204: { description: "No content" },
+ 401: { description: "Unauthorized" },
+ 403: { description: "forbidden" },
+ 404: { description: "Ressource not found" },
+ 500: { description: "Internal server error" },
+ 502: { description: "bad gateway" },
+ 503: { description: "Service unavailable" },
+ },
+ },
+ },
+ validate: {
+ params: likeReviewParams,
+ },
+ },
+ },
+ {
+ method: "GET",
+ path: "/review/{id}/likes",
+ handler: ReviewController.getLikes,
+ options: {
+ description: "get review' likes",
+ tags: ["api"],
+ plugins: {
+ "hapi-swagger": {
+ responses: {
+ 200: { description: "Success" },
+ 204: { description: "No content" },
+ 401: { description: "Unauthorized" },
+ 403: { description: "forbidden" },
+ 404: { description: "Ressource not found" },
+ 500: { description: "Internal server error" },
+ 502: { description: "bad gateway" },
+ 503: { description: "Service unavailable" },
+ },
+ },
+ },
+ validate: {
+ params: likeReviewParams,
+ query: likeReviewQuery,
+ },
+ },
+ },
+ {
+ method: "GET",
+ path: "/reviews/user/{id}",
+ handler: ReviewController.getUserReviews,
+ options: {
+ description: "get review' likes",
+ tags: ["api"],
+ plugins: {
+ "hapi-swagger": {
+ responses: {
+ 200: { description: "Success" },
+ 204: { description: "No content" },
+ 401: { description: "Unauthorized" },
+ 403: { description: "forbidden" },
+ 404: { description: "Ressource not found" },
+ 500: { description: "Internal server error" },
+ 502: { description: "bad gateway" },
+ 503: { description: "Service unavailable" },
+ },
+ },
+ },
+ validate: {
+ params: userReviewParams,
+ query: userReviewQuery,
+ },
+ },
+ },
+ {
+ method: "GET",
+ path: "/reviews/oeuvre/{id}",
+ handler: ReviewController.getOeuvreReviews,
+ options: {
+ description: "get oeuvre reviews",
+ tags: ["api"],
+ plugins: {
+ "hapi-swagger": {
+ responses: {
+ 200: { description: "Success" },
+ 204: { description: "No content" },
+ 401: { description: "Unauthorized" },
+ 403: { description: "forbidden" },
+ 404: { description: "Ressource not found" },
+ 500: { description: "Internal server error" },
+ 502: { description: "bad gateway" },
+ 503: { description: "Service unavailable" },
+ },
+ },
+ },
+ validate: {
+ params: oeuvreReviewParams,
+ query: oeuvreReviewQuery,
+ },
+ },
+ },
+ {
+ method: "GET",
+ path: "/reviews/artist/{id}",
+ handler: ReviewController.getArtistReviews,
+ options: {
+ description: "get artitst' reviews",
+ tags: ["api"],
+ plugins: {
+ "hapi-swagger": {
+ responses: {
+ 200: { description: "Success" },
+ 204: { description: "No content" },
+ 401: { description: "Unauthorized" },
+ 403: { description: "forbidden" },
+ 404: { description: "Ressource not found" },
+ 500: { description: "Internal server error" },
+ 502: { description: "bad gateway" },
+ 503: { description: "Service unavailable" },
+ },
+ },
+ },
+ validate: {
+ params: artistReviewParams,
+ query: artistReviewQuery,
+ },
+ },
+ },
+ {
+ method: "PUT",
+ path: "/review/{id}/comment",
+ handler: ReviewController.putComment,
+ options: {
+ auth: "jwt",
+ description: "put a comment",
+ tags: ["api"],
+ plugins: {
+ "hapi-swagger": {
+ responses: {
+ 200: { description: "Success" },
+ 204: { description: "No content" },
+ 401: { description: "Unauthorized" },
+ 403: { description: "forbidden" },
+ 404: { description: "Ressource not found" },
+ 500: { description: "Internal server error" },
+ 502: { description: "bad gateway" },
+ 503: { description: "Service unavailable" },
+ },
+ },
+ },
+ validate: {
+ params: putCommentParams,
+ payload: putCommentPayload,
+ },
+ },
+ },
+ ]);
+ },
+};
diff --git a/lib/interfaces/routes/spotify.js b/lib/interfaces/routes/spotify.js
index ea35393..0070202 100644
--- a/lib/interfaces/routes/spotify.js
+++ b/lib/interfaces/routes/spotify.js
@@ -1,4 +1,4 @@
-const {trackBody} = require("../../domain/entity/SpotifyEntity")
+const {album, search,track,fetchArtist, fetchArtistSongs } = require("../../domain/entity/SpotifyEntity")
const spotify = require("../controllers/SpotifyController")
module.exports = {
name: 'spotify',
@@ -10,6 +10,133 @@ module.exports = {
method: 'GET',
path: '/spotify/search',
handler: spotify.search,
+ options: {
+ description: 'get a spotify search',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: { description: 'Success' },
+ 204: { description: 'No content' },
+ 401: { description: 'Unauthorized' },
+ 403: { description: 'forbidden' },
+ 404: { description: 'Ressource not found' },
+ 500: { description: 'Internal server error' },
+ 502: { description: 'bad gateway' },
+ 503: { description: 'Service unavailable' },
+ }
+ }
+ },
+ validate: {
+ query: search
+ }
+ },
+ },
+ {
+ method: 'GET',
+ path: '/spotify/Searchfilters',
+ handler: spotify.getSearchFilters,
+ options: {
+ description: 'get spotify search filters',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: { description: 'Success' },
+ 204: { description: 'No content' },
+ 401: { description: 'Unauthorized' },
+ 403: { description: 'forbidden' },
+ 404: { description: 'Ressource not found' },
+ 500: { description: 'Internal server error' },
+ 502: { description: 'bad gateway' },
+ 503: { description: 'Service unavailable' },
+ }
+ }
+ },
+ },
+ },
+ {
+ method: 'GET',
+ path: '/spotify/fetchArtist',
+ handler: spotify.fetchArtist,
+ options: {
+ description: 'get Artist informations',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: { description: 'Success' },
+ 204: { description: 'No content' },
+ 401: { description: 'Unauthorized' },
+ 403: { description: 'forbidden' },
+ 404: { description: 'Ressource not found' },
+ 500: { description: 'Internal server error' },
+ 502: { description: 'bad gateway' },
+ 503: { description: 'Service unavailable' },
+ }
+ }
+ },
+ validate: {
+ query: fetchArtist
+ }
+ },
+ },
+ {
+ method: 'GET',
+ path: '/spotify/fetchArtistSongs',
+ handler: spotify.fetchArtistSongs,
+ options: {
+ description: 'get Artist Songs informations',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: { description: 'Success' },
+ 204: { description: 'No content' },
+ 401: { description: 'Unauthorized' },
+ 403: { description: 'forbidden' },
+ 404: { description: 'Ressource not found' },
+ 500: { description: 'Internal server error' },
+ 502: { description: 'bad gateway' },
+ 503: { description: 'Service unavailable' },
+ }
+ }
+ },
+ validate: {
+ query: fetchArtistSongs
+ }
+ },
+ },
+ {
+ method: 'GET',
+ path: '/spotify/album',
+ handler: spotify.getAlbums,
+ options: {
+ description: 'get a spotify album',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description : 'Success'},
+ 204: {description : 'No content'},
+ 401: {description : 'Unauthorized'},
+ 403: {description : 'forbidden'},
+ 404: {description : 'Ressource not found'},
+ 500: {description : 'Internal server error'},
+ 502: {description : 'bad gateway'},
+ 503: {description : 'Service unavailable'},
+ }
+ }
+ },
+ validate: {
+ query: album
+ }
+ },
+ },
+ {
+ method: 'GET',
+ path: '/spotify/track',
+ handler: spotify.getTracks,
options: {
description: 'get a spotify track',
tags: ['api'],
@@ -28,10 +155,11 @@ module.exports = {
}
},
validate: {
- query: trackBody
+ query: track
}
},
- }
+ },
+
]);
}
};
\ No newline at end of file
diff --git a/lib/interfaces/routes/upload.js b/lib/interfaces/routes/upload.js
new file mode 100644
index 0000000..f0d085e
--- /dev/null
+++ b/lib/interfaces/routes/upload.js
@@ -0,0 +1,30 @@
+'use strict';
+const {userSignUp, userSignIn} = require('../../domain/entity/UserEntity')
+const UploadController = require('../controllers/UploadController');
+
+module.exports = {
+ name: 'upload',
+ version: '1.0.0',
+ register: async (server) => {
+
+ server.route([
+ {
+ method: 'GET',
+ path: '/upload/{filename}',
+ handler: UploadController.getImage,
+ options: {
+ description: 'Create a static image',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description : 'Success'},
+ 204: {description : 'No content'},
+ }
+ }
+ },
+ },
+ },
+ ]);
+ }
+};
\ No newline at end of file
diff --git a/lib/interfaces/routes/users.js b/lib/interfaces/routes/users.js
index cd0415e..dc66e97 100644
--- a/lib/interfaces/routes/users.js
+++ b/lib/interfaces/routes/users.js
@@ -1,6 +1,22 @@
'use strict';
-const {userSignUp, userSignIn} = require('../../domain/entity/UserEntity')
+const {
+ userSignUp,
+ userSignIn,
+ uploadPreview,
+ createUser,
+ isUser,
+ getUserByConfirmToken,
+ sendResetEmail,
+ resetPassword,
+ follow,
+ authWithSpotify,
+ oeuvreFav,
+ getPageQuery,
+ getPageParams,
+ modifyPayload
+} = require('../../domain/entity/UserEntity')
const UsersController = require('../controllers/UsersController');
+const MAX_BYTE_SIZE =20971520
module.exports = {
name: 'users',
version: '1.0.0',
@@ -9,10 +25,10 @@ module.exports = {
server.route([
{
method: 'POST',
- path: '/users/signup',
- handler: UsersController.createUser,
+ path: '/users/confirmUser',
+ handler: UsersController.confirmUser,
options: {
- description: 'Create a user',
+ description: 'Confirm a user',
tags: ['api'],
plugins: {
'hapi-swagger': {
@@ -64,6 +80,315 @@ module.exports = {
}
},
},
+ {
+ method: 'POST',
+ path: '/users/uploadPreviewProfile',
+ handler: UsersController.uploadPreviewProfile,
+ options: {
+ payload: {
+ maxBytes: MAX_BYTE_SIZE, // Set your desired maximum payload size in bytes
+ output: 'stream',
+ parse: true,
+ allow: 'multipart/form-data',
+ multipart: true, // Set multipart to true for handling file uploads
+ },
+ auth: 'jwt',
+ description: 'allow to upload preview profile picture',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description : 'Success'},
+ 204: {description : 'No content'},
+ 401: {description : 'Unauthorized'},
+ 403: {description : 'forbidden'},
+ 404: {description : 'Ressource not found'},
+ 500: {description : 'Internal server error'},
+ 502: {description : 'bad gateway'},
+ 503: {description : 'Service unavailable'},
+ }
+ }
+ },
+ validate: {
+ payload: uploadPreview
+ }
+ },
+ },
+ {
+ method: 'POST',
+ path: '/users/createUser',
+ handler: UsersController.createUser,
+ options: {
+ description: 'send Verification email to create account',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description : 'Success'},
+ 403: {description : 'forbidden'},
+ 500: {description : 'Internal server error'},
+ }
+ }
+ },
+ validate: {
+ payload: createUser
+ }
+ },
+ },
+ {
+ method: 'POST',
+ path: '/users/authWithSpotify',
+ handler: UsersController.authWithSpotify,
+ options: {
+ description: 'send Verification email to create account',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description : 'Success'},
+ 403: {description : 'forbidden'},
+ 500: {description : 'Internal server error'},
+ }
+ }
+ },
+ validate: {
+ payload: authWithSpotify
+ }
+ },
+ },
+ {
+ method: 'GET',
+ path: '/users/isUser',
+ handler: UsersController.isUser,
+ options: {
+ description: 'check if a user exists',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description : 'Success'},
+ 500: {description : 'Internal server error'},
+ }
+ }
+ },
+ validate: {
+ query: isUser
+ }
+ }
+ },
+ {
+ method: 'GET',
+ path: '/users/getUserByConfirmToken',
+ handler: UsersController.getUserByConfirmToken,
+ options: {
+ description: 'get user info',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description: 'Success'},
+ 403: {description : 'forbidden'},
+ 500: {description: 'Internal server error'},
+ }
+ }
+ },
+ validate: {
+ query: getUserByConfirmToken
+ }
+ }
+ },
+ {
+ method: 'POST',
+ path: '/users/sendResetEmail',
+ handler: UsersController.sendResetEmail,
+ options: {
+ description: 'send reset email',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description: 'Success'},
+ 500: {description: 'Internal server error'},
+ }
+ }
+ },
+ validate: {
+ payload: sendResetEmail
+ }
+ }
+ },
+ {
+ method: 'POST',
+ path: '/users/resetPassword',
+ handler: UsersController.resetPassword,
+ options: {
+ description: 'reset user password',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description: 'Success'},
+ 403: {description : 'forbidden'},
+ 500: {description: 'Internal server error'},
+ }
+ }
+ },
+ validate: {
+ payload: resetPassword
+ }
+ }
+ },
+ {
+ method: 'POST',
+ path: '/users/follow',
+ handler: UsersController.follow,
+ options: {
+ auth: 'jwt',
+ description: 'follow artist',
+ tags: ['api'],
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description : 'Success'},
+ 204: {description : 'No content'},
+ 401: {description : 'Unauthorized'},
+ 403: {description : 'forbidden'},
+ 404: {description : 'Ressource not found'},
+ 500: {description : 'Internal server error'},
+ 502: {description : 'bad gateway'},
+ 503: {description : 'Service unavailable'},
+ }
+ }
+ },
+ validate: {
+ payload: follow
+ }
+ },
+ },
+ {
+ method: 'POST',
+ path: '/users/status',
+ handler: UsersController.changePrivateStatus,
+ options: {
+ description: 'set a user in statut private',
+ tags: ['api'],
+ auth: 'jwt',
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description: 'Success'},
+ 403: {description : 'forbidden'},
+ 500: {description: 'Internal server error'},
+ }
+ }
+ },
+ }
+ },
+ {
+ method: 'POST',
+ path: '/users/oeuvreFav',
+ handler: UsersController.oeuvreFav,
+ options: {
+ description: 'add favorite music',
+ tags: ['api'],
+ auth: 'jwt',
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description: 'Success'},
+ 401: {description : 'Unauthorized'},
+ 403: {description : 'forbidden'},
+ 404: {description : 'Ressource not found'},
+ 500: {description: 'Internal server error'},
+ 503: {description : 'Service unavailable'},
+ }
+ }
+ },
+ validate: {
+ payload: oeuvreFav
+ }
+ }
+ },
+ {
+ method: 'GET',
+ path: '/users/getOeuvresFav',
+ handler: UsersController.getOeuvresFav,
+ options: {
+ description: 'get favorites music',
+ tags: ['api'],
+ auth: 'jwt',
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description: 'Success'},
+ 401: {description : 'Unauthorized'},
+ 403: {description : 'forbidden'},
+ 404: {description : 'Ressource not found'},
+ 500: {description: 'Internal server error'},
+ 503: {description : 'Service unavailable'},
+ }
+ }
+ }
+ }
+ },
+ {
+ method: 'GET',
+ path: '/users/{id}/page',
+ handler: UsersController.getPage,
+ options: {
+ description: 'get artist page',
+ tags: ['api'],
+ auth: 'jwt',
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description: 'Success'},
+ 401: {description : 'Unauthorized'},
+ 403: {description : 'forbidden'},
+ 404: {description : 'Ressource not found'},
+ 500: {description: 'Internal server error'},
+ 503: {description : 'Service unavailable'},
+ }
+ }
+ },
+ validate: {
+ query: getPageQuery,
+ params: getPageParams
+ }
+ }
+ },
+ {
+ method: 'POST',
+ path: '/users/modify',
+ handler: UsersController.modify,
+ options: {
+ description: 'modify user info',
+ tags: ['api'],
+ auth: 'jwt',
+ payload: {
+ maxBytes: MAX_BYTE_SIZE, // Set your desired maximum payload size in bytes
+ output: 'stream',
+ parse: true,
+ allow: 'multipart/form-data',
+ multipart: true, // Set multipart to true for handling file uploads
+ },
+ plugins: {
+ 'hapi-swagger': {
+ responses: {
+ 200: {description: 'Success'},
+ 401: {description : 'Unauthorized'},
+ 403: {description : 'forbidden'},
+ 404: {description : 'Ressource not found'},
+ 500: {description: 'Internal server error'},
+ 503: {description : 'Service unavailable'},
+ }
+ }
+ },
+ validate: {
+ payload: modifyPayload,
+ }
+ }
+ }
]);
}
};
\ No newline at end of file
diff --git a/lib/interfaces/serializers/AlbumSerializer.js b/lib/interfaces/serializers/AlbumSerializer.js
index 508d554..277161e 100644
--- a/lib/interfaces/serializers/AlbumSerializer.js
+++ b/lib/interfaces/serializers/AlbumSerializer.js
@@ -1,17 +1,26 @@
-const Album = require("../../domain/model/Album")
-const ArtistSerializer = require("./ArtistSerializer")
+const Album = require("../../domain/model/Album");
+const SerializeArtist = require("./ArtistSerializer");
+const SerializeTrack = require("./AlbumTrackSerializer");
+
const serializeAlbum = (albumRaw) => {
+ const tracks = albumRaw.tracks?.items ? albumRaw.tracks?.items.map(item => SerializeTrack(item)) : undefined
const album = {
id: albumRaw.id,
total_tracks: albumRaw.total_tracks,
spotify_url : albumRaw.external_urls.spotify,
name: albumRaw.name,
- images: albumRaw.images,
+ image: albumRaw?.images ? albumRaw.images[0].url : null,
release_date : albumRaw.release_date,
- artists : albumRaw?.artists?.map(item => ArtistSerializer(item)),
+ artists : albumRaw?.artists?.map(item => SerializeArtist(item)),
+ tracks: tracks,
genres : albumRaw?.genres,
- popularity: albumRaw.popularity ? albumRaw.popularity : Math.floor(Math.random() * 100)
- }
+ rating: albumRaw?.rating,
+ reviewCount: albumRaw?.reviewCount,
+ type : albumRaw?.album_type, // utilise album_group (plus precis pour fetchArtistSongs pour recuperer appears_on) sinon album_type (present dans fetchAlbum et fetchArtistSongs, n'a pas appears_on)
+ likeCount: albumRaw?.likeCount,
+ popularity: albumRaw.popularity ? albumRaw.popularity : Math.floor(Math.random() * 100),
+ };
return new Album(album)
}
-module.exports = serializeAlbum
\ No newline at end of file
+
+module.exports = serializeAlbum
diff --git a/lib/interfaces/serializers/AlbumTrackSerializer.js b/lib/interfaces/serializers/AlbumTrackSerializer.js
new file mode 100644
index 0000000..26b4d5c
--- /dev/null
+++ b/lib/interfaces/serializers/AlbumTrackSerializer.js
@@ -0,0 +1,18 @@
+// TrackSerializer.js
+const Track = require("../../domain/model/Track");
+const SerializeArtist = require("./ArtistSerializer");
+
+const serializeTrack = (trackRaw) => {
+ const track = {
+ id: trackRaw.id,
+ name: trackRaw.name,
+ spotify_url : trackRaw?.external_urls.spotify,
+ duration_ms: trackRaw.duration_ms,
+ rating: trackRaw?.rating,
+ likeCount: trackRaw?.likeCount,
+ reviewCount: trackRaw?.reviewCount,
+ };
+ return new Track(track)
+};
+
+module.exports = serializeTrack
\ No newline at end of file
diff --git a/lib/interfaces/serializers/ArtistSerializer.js b/lib/interfaces/serializers/ArtistSerializer.js
index 2bd457b..24f1358 100644
--- a/lib/interfaces/serializers/ArtistSerializer.js
+++ b/lib/interfaces/serializers/ArtistSerializer.js
@@ -1,13 +1,17 @@
-const Artist = require("../../domain/model/Artist")
+const Artist = require("../../domain/model/Artist");
const serializeArtiste = (artisteRaw) => {
- const artist = {
- id: artisteRaw.id,
- name: artisteRaw.name,
- images: artisteRaw?.images,
- spotify_url : artisteRaw?.external_urls?.spotify,
- popularity: artisteRaw?.popularity,
- genres : artisteRaw?.genres
- }
- return new Artist(artist)
-}
-module.exports=serializeArtiste
\ No newline at end of file
+ const artist = {
+ id: artisteRaw.id,
+ name: artisteRaw.name,
+ follower_count: artisteRaw?.follower_count,
+ image:
+ artisteRaw?.images && artisteRaw.images.length > 0
+ ? artisteRaw.images[0].url
+ : null,
+ spotify_url: artisteRaw?.external_urls?.spotify,
+ popularity: artisteRaw?.popularity,
+ genres: artisteRaw?.genres,
+ };
+ return new Artist(artist);
+};
+module.exports = serializeArtiste;
diff --git a/lib/interfaces/serializers/OeuvreSerializer.js b/lib/interfaces/serializers/OeuvreSerializer.js
new file mode 100644
index 0000000..9899f3d
--- /dev/null
+++ b/lib/interfaces/serializers/OeuvreSerializer.js
@@ -0,0 +1,20 @@
+const artistSerializer = require("./ArtistSerializer");
+const trackSerializer = require("./TrackSerializer");
+const albumSerializer = require("./AlbumSerializer");
+const oeuvreSerializer = (rawOeuvre, type) => {
+ console.log(type);
+ switch (type) {
+ case "artist":
+ return artistSerializer(rawOeuvre);
+ case "track":
+ return trackSerializer(rawOeuvre);
+ case "album":
+ return albumSerializer(rawOeuvre);
+ case "single":
+ return albumSerializer(rawOeuvre);
+ default:
+ return null;
+ }
+};
+
+module.exports = oeuvreSerializer;
diff --git a/lib/interfaces/serializers/ReviewSerializer.js b/lib/interfaces/serializers/ReviewSerializer.js
new file mode 100644
index 0000000..8ed09d2
--- /dev/null
+++ b/lib/interfaces/serializers/ReviewSerializer.js
@@ -0,0 +1,56 @@
+const artistSerializer = require("./ArtistSerializer");
+const trackSerializer = require("./TrackSerializer");
+const albumSerializer = require("./AlbumSerializer");
+const UserPublic = require("../../domain/model/UserPublic");
+const ReviewPublic = require("../../domain/model/ReviewPublic");
+const serializeReview = async (
+ rawReview,
+ id_utilisateur,
+ comments,
+ spotifyRepository,
+ reviewRepository,
+ friendRepository
+) => {
+ let doesUserLike = false;
+ if (id_utilisateur) {
+ doesUserLike = await reviewRepository.doesUserLikes(
+ id_utilisateur,
+ rawReview.id_review
+ );
+ }
+ let rawOeuvre = await spotifyRepository.getOeuvre(
+ rawReview.id_oeuvre,
+ rawReview.type
+ );
+ if (rawOeuvre.error)
+ throwStatusCode(rawOeuvre.error.status, rawOeuvre.error.message);
+ rawReview.made_by_friend = await friendRepository.areFriends(
+ id_utilisateur,
+ rawReview.utilisateur.id_utilisateur
+ );
+ switch (rawReview.type) {
+ case "artist":
+ rawOeuvre = artistSerializer(rawOeuvre);
+ break;
+ case "track":
+ rawOeuvre = trackSerializer(rawOeuvre);
+ break;
+ case "album":
+ rawOeuvre = albumSerializer(rawOeuvre);
+ break;
+ case "single":
+ rawOeuvre = albumSerializer(rawOeuvre);
+ break;
+ default:
+ rawOeuvre = null;
+ }
+ return new ReviewPublic(
+ rawReview,
+ rawOeuvre,
+ new UserPublic(rawReview.utilisateur),
+ doesUserLike,
+ comments
+ );
+};
+
+module.exports = serializeReview;
diff --git a/lib/interfaces/serializers/SerializeSearchItem.js b/lib/interfaces/serializers/SerializeSearchItem.js
new file mode 100644
index 0000000..96349f1
--- /dev/null
+++ b/lib/interfaces/serializers/SerializeSearchItem.js
@@ -0,0 +1,57 @@
+const seralizer = {
+ 'artist': (item) => {
+ return {
+ id: item.id,
+ imageURL: item.image,
+ title: item.name,
+ subtitle: ''
+ }
+
+ },
+ 'album': (item) => {
+ return {
+ id: item.id,
+ imageURL: item.image,
+ title: item.name,
+ subtitle: item?.artists[0].name
+ }
+ },
+ 'track': (item) => {
+ return {
+ id: item.id,
+ imageURL: item.album.image,
+ title: item.name,
+ subtitle: item?.artists[0].name
+ }
+ },
+ 'single': (item) => {
+ return {
+ id: item.id,
+
+ imageURL: item.image,
+ title: item.name,
+ subtitle: item?.artists[0].name
+ }
+ },
+ 'compilation': (item) => {
+ return {
+ id: item.id,
+ imageURL: item.image,
+ title: item.name,
+ subtitle: item?.artists[0].name
+ }
+ },
+ 'user': (item) => {
+ return {
+ id: item.id_utilisateur,
+ imageURL: item.photo,
+ title: item.alias,
+ subtitle: item.pseudo
+ }
+ }
+}
+module.exports = (item) => {
+ const value = seralizer[item.type](item)
+ value.type = item.type
+ return value
+}
\ No newline at end of file
diff --git a/lib/interfaces/serializers/TrackSerializer.js b/lib/interfaces/serializers/TrackSerializer.js
index 66600e1..41f6af9 100644
--- a/lib/interfaces/serializers/TrackSerializer.js
+++ b/lib/interfaces/serializers/TrackSerializer.js
@@ -1,18 +1,27 @@
-const Track = require("../../domain/model/Track")
-const SerializeAlbum = require("./AlbumSerializer")
-const SerializeArtist = require("./ArtistSerializer")
+// TrackSerializer.js
+const Track = require("../../domain/model/Track");
+const SerializeAlbum = require("./AlbumSerializer");
+const SerializeArtist = require("./ArtistSerializer");
+
const serializeTrack = (trackRaw) => {
- const album = trackRaw.album ? SerializeAlbum(trackRaw?.album) : undefined
- const track = {
- id: trackRaw.id,
- name: trackRaw.name,
- album: album,
- artists: trackRaw?.artists?.map(item => SerializeArtist(item)),
- spotify_url : trackRaw.external_urls.spotify,
- duration_ms: trackRaw.duration_ms,
- popularity:trackRaw.popularity,
- }
- return new Track(track)
-}
+ const album = trackRaw?.album ? SerializeAlbum(trackRaw.album) : undefined;
+ const track = {
+ id: trackRaw.id,
+ name: trackRaw.name,
+ album: album,
+ artists: trackRaw?.artists
+ ? trackRaw?.artists?.map((item) => SerializeArtist(item))
+ : undefined,
+ spotify_url: trackRaw.external_urls.spotify,
+ duration_ms: trackRaw?.duration_ms,
+ popularity: trackRaw?.popularity ? trackRaw?.popularity : undefined,
+ rating: trackRaw?.rating,
+ likeCount: trackRaw?.likeCount,
+ reviewCount: trackRaw?.reviewCount,
+ release_date: trackRaw?.album?.release_date,
+ };
+
+ return new Track(track);
+};
-module.exports = serializeTrack
\ No newline at end of file
+module.exports = serializeTrack;
diff --git a/package-lock.json b/package-lock.json
index bd5d4df..fc743dd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,861 +1,1025 @@
{
"name": "nodejs-clean-architecture-app",
"version": "1.0.0",
- "lockfileVersion": 1,
+ "lockfileVersion": 3,
"requires": true,
- "dependencies": {
- "@babel/code-frame": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz",
- "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==",
- "dev": true,
- "requires": {
- "@babel/highlight": "^7.10.1"
- }
- },
- "@babel/core": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.1.tgz",
- "integrity": "sha512-u8XiZ6sMXW/gPmoP5ijonSUln4unazG291X0XAQ5h0s8qnAFr6BRRZGUEK+jtRWdmB0NTJQt7Uga25q8GetIIg==",
- "dev": true,
- "requires": {
- "@babel/code-frame": "^7.10.1",
- "@babel/generator": "^7.10.1",
- "@babel/helper-module-transforms": "^7.10.1",
- "@babel/helpers": "^7.10.1",
- "@babel/parser": "^7.10.1",
- "@babel/template": "^7.10.1",
- "@babel/traverse": "^7.10.1",
- "@babel/types": "^7.10.1",
- "convert-source-map": "^1.7.0",
- "debug": "^4.1.0",
- "gensync": "^1.0.0-beta.1",
- "json5": "^2.1.2",
- "lodash": "^4.17.13",
- "resolve": "^1.3.2",
- "semver": "^5.4.1",
- "source-map": "^0.5.0"
+ "packages": {
+ "": {
+ "name": "nodejs-clean-architecture-app",
+ "version": "1.0.0",
+ "dependencies": {
+ "@hapi/boom": "^10.0.1",
+ "@hapi/hapi": "^21.3.2",
+ "@hapi/inert": "^7.1.0",
+ "@hapi/joi": "^17.1.1",
+ "@hapi/jwt": "^3.2.0",
+ "@hapi/vision": "^7.0.3",
+ "axios": "^1.5.1",
+ "bcrypt": "^5.1.1",
+ "blipp": "^4.0.2",
+ "dotenv": "^8.6.0",
+ "hapi-cors": "^1.0.3",
+ "hapi-swagger": "^17.2.1",
+ "install": "^0.13.0",
+ "joi": "^17.10.0",
+ "jsonwebtoken": "^8.5.1",
+ "mysql2": "^3.6.0",
+ "nodemailer": "^6.9.7",
+ "npm": "^10.2.5",
+ "request": "^2.88.2",
+ "sequelize": "^5.21.11",
+ "underscore": "^1.13.6"
+ },
+ "devDependencies": {
+ "husky": "^8.0.3",
+ "jest": "^28.0.0",
+ "nodemon": "^2.0.4",
+ "sequelize-mock": "^0.10.2"
},
+ "engines": {
+ "node": ">=12",
+ "npm": ">=6.12"
+ }
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+ "dev": true,
"dependencies": {
- "debug": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
- "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
- "dev": true,
- "requires": {
- "ms": "^2.1.1"
- }
- },
- "source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
- "dev": true
- }
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@apidevtools/json-schema-ref-parser": {
+ "version": "11.5.4",
+ "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.5.4.tgz",
+ "integrity": "sha512-o2fsypTGU0WxRxbax8zQoHiIB4dyrkwYfcm8TxZ+bx9pCzcWZbQtiMqpgBvWA/nJ2TrGjK5adCLfTH8wUeU/Wg==",
+ "dependencies": {
+ "@jsdevtools/ono": "^7.1.3",
+ "@types/json-schema": "^7.0.15",
+ "js-yaml": "^4.1.0"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/philsturgeon"
+ }
+ },
+ "node_modules/@apidevtools/openapi-schemas": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz",
+ "integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@apidevtools/swagger-methods": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz",
+ "integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg=="
+ },
+ "node_modules/@apidevtools/swagger-parser": {
+ "version": "10.0.3",
+ "resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-10.0.3.tgz",
+ "integrity": "sha512-sNiLY51vZOmSPFZA5TF35KZ2HbgYklQnTSDnkghamzLb3EkNtcQnrBQEj5AOCxHpTtXpqMCRM1CrmV2rG6nw4g==",
+ "dependencies": {
+ "@apidevtools/json-schema-ref-parser": "^9.0.6",
+ "@apidevtools/openapi-schemas": "^2.0.4",
+ "@apidevtools/swagger-methods": "^3.0.2",
+ "@jsdevtools/ono": "^7.1.3",
+ "call-me-maybe": "^1.0.1",
+ "z-schema": "^5.0.1"
+ },
+ "peerDependencies": {
+ "openapi-types": ">=7"
+ }
+ },
+ "node_modules/@apidevtools/swagger-parser/node_modules/@apidevtools/json-schema-ref-parser": {
+ "version": "9.1.2",
+ "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.1.2.tgz",
+ "integrity": "sha512-r1w81DpR+KyRWd3f+rk6TNqMgedmAxZP5v5KWlXQWlgMUUtyEJch0DKEci1SorPMiSeM8XPl7MZ3miJ60JIpQg==",
+ "dependencies": {
+ "@jsdevtools/ono": "^7.1.3",
+ "@types/json-schema": "^7.0.6",
+ "call-me-maybe": "^1.0.1",
+ "js-yaml": "^4.1.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
+ "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.23.4",
+ "chalk": "^2.4.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
}
},
- "@babel/generator": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.1.tgz",
- "integrity": "sha512-AT0YPLQw9DI21tliuJIdplVfLHya6mcGa8ctkv7n4Qv+hYacJrKmNWIteAK1P9iyLikFIAkwqJ7HAOqIDLFfgA==",
+ "node_modules/@babel/code-frame/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
- "requires": {
- "@babel/types": "^7.10.1",
- "jsesc": "^2.5.1",
- "lodash": "^4.17.13",
- "source-map": "^0.5.0"
+ "dependencies": {
+ "color-convert": "^1.9.0"
},
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
"dependencies": {
- "source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
- "dev": true
- }
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
}
},
- "@babel/helper-function-name": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz",
- "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==",
+ "node_modules/@babel/code-frame/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
- "requires": {
- "@babel/helper-get-function-arity": "^7.10.1",
- "@babel/template": "^7.10.1",
- "@babel/types": "^7.10.1"
+ "dependencies": {
+ "color-name": "1.1.3"
}
},
- "@babel/helper-get-function-arity": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz",
- "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==",
+ "node_modules/@babel/code-frame/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "node_modules/@babel/code-frame/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"dev": true,
- "requires": {
- "@babel/types": "^7.10.1"
+ "engines": {
+ "node": ">=0.8.0"
}
},
- "@babel/helper-member-expression-to-functions": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz",
- "integrity": "sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g==",
+ "node_modules/@babel/code-frame/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true,
- "requires": {
- "@babel/types": "^7.10.1"
+ "engines": {
+ "node": ">=4"
}
},
- "@babel/helper-module-imports": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz",
- "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==",
+ "node_modules/@babel/code-frame/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
- "requires": {
- "@babel/types": "^7.10.1"
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
}
},
- "@babel/helper-module-transforms": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz",
- "integrity": "sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg==",
+ "node_modules/@babel/compat-data": {
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz",
+ "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==",
"dev": true,
- "requires": {
- "@babel/helper-module-imports": "^7.10.1",
- "@babel/helper-replace-supers": "^7.10.1",
- "@babel/helper-simple-access": "^7.10.1",
- "@babel/helper-split-export-declaration": "^7.10.1",
- "@babel/template": "^7.10.1",
- "@babel/types": "^7.10.1",
- "lodash": "^4.17.13"
+ "engines": {
+ "node": ">=6.9.0"
}
},
- "@babel/helper-optimise-call-expression": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz",
- "integrity": "sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg==",
+ "node_modules/@babel/core": {
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.0.tgz",
+ "integrity": "sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==",
"dev": true,
- "requires": {
- "@babel/types": "^7.10.1"
+ "dependencies": {
+ "@ampproject/remapping": "^2.2.0",
+ "@babel/code-frame": "^7.23.5",
+ "@babel/generator": "^7.23.6",
+ "@babel/helper-compilation-targets": "^7.23.6",
+ "@babel/helper-module-transforms": "^7.23.3",
+ "@babel/helpers": "^7.24.0",
+ "@babel/parser": "^7.24.0",
+ "@babel/template": "^7.24.0",
+ "@babel/traverse": "^7.24.0",
+ "@babel/types": "^7.24.0",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
}
},
- "@babel/helper-plugin-utils": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz",
- "integrity": "sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==",
+ "node_modules/@babel/core/node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"dev": true
},
- "@babel/helper-replace-supers": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz",
- "integrity": "sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A==",
+ "node_modules/@babel/core/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz",
+ "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.23.6",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "@jridgewell/trace-mapping": "^0.3.17",
+ "jsesc": "^2.5.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz",
+ "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==",
"dev": true,
- "requires": {
- "@babel/helper-member-expression-to-functions": "^7.10.1",
- "@babel/helper-optimise-call-expression": "^7.10.1",
- "@babel/traverse": "^7.10.1",
- "@babel/types": "^7.10.1"
+ "dependencies": {
+ "@babel/compat-data": "^7.23.5",
+ "@babel/helper-validator-option": "^7.23.5",
+ "browserslist": "^4.22.2",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
}
},
- "@babel/helper-simple-access": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz",
- "integrity": "sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw==",
+ "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
"dev": true,
- "requires": {
- "@babel/template": "^7.10.1",
- "@babel/types": "^7.10.1"
+ "dependencies": {
+ "yallist": "^3.0.2"
}
},
- "@babel/helper-split-export-declaration": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz",
- "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==",
+ "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
- "requires": {
- "@babel/types": "^7.10.1"
+ "bin": {
+ "semver": "bin/semver.js"
}
},
- "@babel/helper-validator-identifier": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz",
- "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==",
+ "node_modules/@babel/helper-compilation-targets/node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
"dev": true
},
- "@babel/helpers": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.1.tgz",
- "integrity": "sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw==",
+ "node_modules/@babel/helper-environment-visitor": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+ "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-function-name": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+ "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.22.15",
+ "@babel/types": "^7.23.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-hoist-variables": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+ "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz",
+ "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz",
+ "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-module-imports": "^7.22.15",
+ "@babel/helper-simple-access": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/helper-validator-identifier": "^7.22.20"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz",
+ "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-simple-access": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
+ "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.22.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
+ "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.23.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
+ "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+ "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz",
+ "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==",
"dev": true,
- "requires": {
- "@babel/template": "^7.10.1",
- "@babel/traverse": "^7.10.1",
- "@babel/types": "^7.10.1"
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.0.tgz",
+ "integrity": "sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.24.0",
+ "@babel/traverse": "^7.24.0",
+ "@babel/types": "^7.24.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
}
},
- "@babel/highlight": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz",
- "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==",
+ "node_modules/@babel/highlight": {
+ "version": "7.23.4",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
+ "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
"dev": true,
- "requires": {
- "@babel/helper-validator-identifier": "^7.10.1",
- "chalk": "^2.0.0",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "chalk": "^2.4.2",
"js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
}
},
- "@babel/parser": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.1.tgz",
- "integrity": "sha512-AUTksaz3FqugBkbTZ1i+lDLG5qy8hIzCaAxEtttU6C0BtZZU9pkNZtWSVAht4EW9kl46YBiyTGMp9xTTGqViNg==",
+ "node_modules/@babel/highlight/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
"dev": true
},
- "@babel/plugin-syntax-async-generators": {
+ "node_modules/@babel/highlight/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz",
+ "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-async-generators": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
"integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
"dev": true,
- "requires": {
+ "dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "@babel/plugin-syntax-bigint": {
+ "node_modules/@babel/plugin-syntax-bigint": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
"integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
"dev": true,
- "requires": {
+ "dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-properties": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+ "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.12.13"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "@babel/plugin-syntax-class-properties": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.1.tgz",
- "integrity": "sha512-Gf2Yx/iRs1JREDtVZ56OrjjgFHCaldpTnuy9BHla10qyVT3YkIIGEtoDWhyop0ksu1GvNjHIoYRBqm3zoR1jyQ==",
+ "node_modules/@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
"dev": true,
- "requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "@babel/plugin-syntax-json-strings": {
+ "node_modules/@babel/plugin-syntax-json-strings": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
"integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
"dev": true,
- "requires": {
+ "dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "@babel/plugin-syntax-logical-assignment-operators": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.1.tgz",
- "integrity": "sha512-XyHIFa9kdrgJS91CUH+ccPVTnJShr8nLGc5bG2IhGXv5p1Rd+8BleGE5yzIg2Nc1QZAdHDa0Qp4m6066OL96Iw==",
+ "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
"dev": true,
- "requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "@babel/plugin-syntax-nullish-coalescing-operator": {
+ "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
"integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
"dev": true,
- "requires": {
+ "dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "@babel/plugin-syntax-numeric-separator": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.1.tgz",
- "integrity": "sha512-uTd0OsHrpe3tH5gRPTxG8Voh99/WCU78vIm5NMRYPAqC8lR4vajt6KkCAknCHrx24vkPdd/05yfdGSB4EIY2mg==",
+ "node_modules/@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
"dev": true,
- "requires": {
- "@babel/helper-plugin-utils": "^7.10.1"
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "@babel/plugin-syntax-object-rest-spread": {
+ "node_modules/@babel/plugin-syntax-object-rest-spread": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
"integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
"dev": true,
- "requires": {
+ "dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "@babel/plugin-syntax-optional-catch-binding": {
+ "node_modules/@babel/plugin-syntax-optional-catch-binding": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
"integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
"dev": true,
- "requires": {
+ "dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "@babel/plugin-syntax-optional-chaining": {
+ "node_modules/@babel/plugin-syntax-optional-chaining": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
"integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
"dev": true,
- "requires": {
+ "dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "@babel/template": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz",
- "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==",
+ "node_modules/@babel/plugin-syntax-top-level-await": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
"dev": true,
- "requires": {
- "@babel/code-frame": "^7.10.1",
- "@babel/parser": "^7.10.1",
- "@babel/types": "^7.10.1"
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
}
},
- "@babel/traverse": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz",
- "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==",
+ "node_modules/@babel/plugin-syntax-typescript": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz",
+ "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==",
"dev": true,
- "requires": {
- "@babel/code-frame": "^7.10.1",
- "@babel/generator": "^7.10.1",
- "@babel/helper-function-name": "^7.10.1",
- "@babel/helper-split-export-declaration": "^7.10.1",
- "@babel/parser": "^7.10.1",
- "@babel/types": "^7.10.1",
- "debug": "^4.1.0",
- "globals": "^11.1.0",
- "lodash": "^4.17.13"
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz",
+ "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.23.5",
+ "@babel/parser": "^7.24.0",
+ "@babel/types": "^7.24.0"
},
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.0.tgz",
+ "integrity": "sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==",
+ "dev": true,
"dependencies": {
- "debug": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
- "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
- "dev": true,
- "requires": {
- "ms": "^2.1.1"
- }
- }
+ "@babel/code-frame": "^7.23.5",
+ "@babel/generator": "^7.23.6",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.23.0",
+ "@babel/helper-hoist-variables": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/parser": "^7.24.0",
+ "@babel/types": "^7.24.0",
+ "debug": "^4.3.1",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
}
},
- "@babel/types": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.1.tgz",
- "integrity": "sha512-L2yqUOpf3tzlW9GVuipgLEcZxnO+96SzR6fjXMuxxNkIgFJ5+07mHCZ+HkHqaeZu8+3LKnNJJ1bKbjBETQAsrA==",
+ "node_modules/@babel/types": {
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz",
+ "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==",
"dev": true,
- "requires": {
- "@babel/helper-validator-identifier": "^7.10.1",
- "lodash": "^4.17.13",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.23.4",
+ "@babel/helper-validator-identifier": "^7.22.20",
"to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
}
},
- "@bcoe/v8-coverage": {
+ "node_modules/@bcoe/v8-coverage": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
"dev": true
},
- "@cnakazawa/watch": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz",
- "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==",
- "dev": true,
- "requires": {
- "exec-sh": "^0.3.2",
- "minimist": "^1.2.0"
+ "node_modules/@hapi/accept": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/@hapi/accept/-/accept-6.0.3.tgz",
+ "integrity": "sha512-p72f9k56EuF0n3MwlBNThyVE5PXX40g+aQh+C/xbKrfzahM2Oispv3AXmOIU51t3j77zay1qrX7IIziZXspMlw==",
+ "dependencies": {
+ "@hapi/boom": "^10.0.1",
+ "@hapi/hoek": "^11.0.2"
}
},
- "@hapi/accept": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/@hapi/accept/-/accept-5.0.2.tgz",
- "integrity": "sha512-CmzBx/bXUR8451fnZRuZAJRlzgm0Jgu5dltTX/bszmR2lheb9BpyN47Q1RbaGTsvFzn0PXAEs+lXDKfshccYZw==",
- "requires": {
- "@hapi/boom": "9.x.x",
- "@hapi/hoek": "9.x.x"
- },
+ "node_modules/@hapi/address": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/@hapi/address/-/address-4.1.0.tgz",
+ "integrity": "sha512-SkszZf13HVgGmChdHo/PxchnSaCJ6cetVqLzyciudzZRT0jcOouIF/Q93mgjw8cce+D+4F4C1Z/WrfFN+O3VHQ==",
+ "deprecated": "Moved to 'npm install @sideway/address'",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- }
+ "@hapi/hoek": "^9.0.0"
}
},
- "@hapi/address": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.2.tgz",
- "integrity": "sha512-O4QDrx+JoGKZc6aN64L04vqa7e41tIiLU+OvKdcYaEMP97UttL0f9GIi9/0A4WAMx0uBd6SidDIhktZhgOcN8Q=="
+ "node_modules/@hapi/address/node_modules/@hapi/hoek": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
+ "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
},
- "@hapi/ammo": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/@hapi/ammo/-/ammo-5.0.1.tgz",
- "integrity": "sha512-FbCNwcTbnQP4VYYhLNGZmA76xb2aHg9AMPiy18NZyWMG310P5KdFGyA9v2rm5ujrIny77dEEIkMOwl0Xv+fSSA==",
- "requires": {
- "@hapi/hoek": "9.x.x"
- },
+ "node_modules/@hapi/ammo": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/ammo/-/ammo-6.0.1.tgz",
+ "integrity": "sha512-pmL+nPod4g58kXrMcsGLp05O2jF4P2Q3GiL8qYV7nKYEh3cGf+rV4P5Jyi2Uq0agGhVU63GtaSAfBEZOlrJn9w==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.0.4",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.4.tgz",
- "integrity": "sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw=="
- }
+ "@hapi/hoek": "^11.0.2"
}
},
- "@hapi/b64": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/b64/-/b64-5.0.0.tgz",
- "integrity": "sha512-ngu0tSEmrezoiIaNGG6rRvKOUkUuDdf4XTPnONHGYfSGRmDqPZX5oJL6HAdKTo1UQHECbdB4OzhWrfgVppjHUw==",
- "requires": {
- "@hapi/hoek": "9.x.x"
- },
+ "node_modules/@hapi/b64": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/b64/-/b64-6.0.1.tgz",
+ "integrity": "sha512-ZvjX4JQReUmBheeCq+S9YavcnMMHWqx3S0jHNXWIM1kQDxB9cyfSycpVvjfrKcIS8Mh5N3hmu/YKo4Iag9g2Kw==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- }
- }
- },
- "@hapi/basic": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/@hapi/basic/-/basic-5.1.1.tgz",
- "integrity": "sha512-fHyVvf2xurgGBJJaLpRMtDF4AaPSs679nGk8/FjBw3p8/Kj5fuPv5kD1+fJ4ZSdPt1rHHGvKIDK0aVysbbUDMg==",
- "requires": {
- "@hapi/boom": "7.x.x",
- "@hapi/hoek": "8.x.x"
- },
- "dependencies": {
- "@hapi/boom": {
- "version": "7.4.11",
- "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-7.4.11.tgz",
- "integrity": "sha512-VSU/Cnj1DXouukYxxkes4nNJonCnlogHvIff1v1RVoN4xzkKhMXX+GRmb3NyH1iar10I9WFPDv2JPwfH3GaV0A==",
- "requires": {
- "@hapi/hoek": "8.x.x"
- }
- }
+ "@hapi/hoek": "^11.0.2"
}
},
- "@hapi/boom": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-9.1.0.tgz",
- "integrity": "sha512-4nZmpp4tXbm162LaZT45P7F7sgiem8dwAh2vHWT6XX24dozNjGMg6BvKCRvtCUcmcXqeMIUqWN8Rc5X8yKuROQ==",
- "requires": {
- "@hapi/hoek": "9.x.x"
- },
+ "node_modules/@hapi/boom": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-10.0.1.tgz",
+ "integrity": "sha512-ERcCZaEjdH3OgSJlyjVk8pHIFeus91CjKP3v+MpgBNp5IvGzP2l/bRiD78nqYcKPaZdbKkK5vDBVPd2ohHBlsA==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.0.4",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.4.tgz",
- "integrity": "sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw=="
- }
+ "@hapi/hoek": "^11.0.2"
}
},
- "@hapi/bounce": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/bounce/-/bounce-2.0.0.tgz",
- "integrity": "sha512-JesW92uyzOOyuzJKjoLHM1ThiOvHPOLDHw01YV8yh5nCso7sDwJho1h0Ad2N+E62bZyz46TG3xhAi/78Gsct6A==",
- "requires": {
- "@hapi/boom": "9.x.x",
- "@hapi/hoek": "9.x.x"
- },
+ "node_modules/@hapi/bounce": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/bounce/-/bounce-3.0.1.tgz",
+ "integrity": "sha512-G+/Pp9c1Ha4FDP+3Sy/Xwg2O4Ahaw3lIZFSX+BL4uWi64CmiETuZPxhKDUD4xBMOUZbBlzvO8HjiK8ePnhBadA==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.0.4",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.4.tgz",
- "integrity": "sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw=="
- }
+ "@hapi/boom": "^10.0.1",
+ "@hapi/hoek": "^11.0.2"
}
},
- "@hapi/bourne": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz",
- "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA=="
+ "node_modules/@hapi/bourne": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-3.0.0.tgz",
+ "integrity": "sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w=="
},
- "@hapi/call": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/@hapi/call/-/call-8.0.1.tgz",
- "integrity": "sha512-bOff6GTdOnoe5b8oXRV3lwkQSb/LAWylvDMae6RgEWWntd0SHtkYbQukDHKlfaYtVnSAgIavJ0kqszF/AIBb6g==",
- "requires": {
- "@hapi/boom": "9.x.x",
- "@hapi/hoek": "9.x.x"
- },
+ "node_modules/@hapi/call": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/call/-/call-9.0.1.tgz",
+ "integrity": "sha512-uPojQRqEL1GRZR4xXPqcLMujQGaEpyVPRyBlD8Pp5rqgIwLhtveF9PkixiKru2THXvuN8mUrLeet5fqxKAAMGg==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- }
+ "@hapi/boom": "^10.0.1",
+ "@hapi/hoek": "^11.0.2"
}
},
- "@hapi/catbox": {
- "version": "11.1.1",
- "resolved": "https://registry.npmjs.org/@hapi/catbox/-/catbox-11.1.1.tgz",
- "integrity": "sha512-u/8HvB7dD/6X8hsZIpskSDo4yMKpHxFd7NluoylhGrL6cUfYxdQPnvUp9YU2C6F9hsyBVLGulBd9vBN1ebfXOQ==",
- "requires": {
- "@hapi/boom": "9.x.x",
- "@hapi/hoek": "9.x.x",
- "@hapi/podium": "4.x.x",
- "@hapi/validate": "1.x.x"
- },
+ "node_modules/@hapi/catbox": {
+ "version": "12.1.1",
+ "resolved": "https://registry.npmjs.org/@hapi/catbox/-/catbox-12.1.1.tgz",
+ "integrity": "sha512-hDqYB1J+R0HtZg4iPH3LEnldoaBsar6bYp0EonBmNQ9t5CO+1CqgCul2ZtFveW1ReA5SQuze9GPSU7/aecERhw==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- }
+ "@hapi/boom": "^10.0.1",
+ "@hapi/hoek": "^11.0.2",
+ "@hapi/podium": "^5.0.0",
+ "@hapi/validate": "^2.0.1"
}
},
- "@hapi/catbox-memory": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/@hapi/catbox-memory/-/catbox-memory-5.0.1.tgz",
- "integrity": "sha512-QWw9nOYJq5PlvChLWV8i6hQHJYfvdqiXdvTupJFh0eqLZ64Xir7mKNi96d5/ZMUAqXPursfNDIDxjFgoEDUqeQ==",
- "requires": {
- "@hapi/boom": "9.x.x",
- "@hapi/hoek": "9.x.x"
- },
+ "node_modules/@hapi/catbox-memory": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/catbox-memory/-/catbox-memory-6.0.1.tgz",
+ "integrity": "sha512-sVb+/ZxbZIvaMtJfAbdyY+QJUQg9oKTwamXpEg/5xnfG5WbJLTjvEn4kIGKz9pN3ENNbIL/bIdctmHmqi/AdGA==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- }
+ "@hapi/boom": "^10.0.1",
+ "@hapi/hoek": "^11.0.2"
}
},
- "@hapi/catbox-object": {
+ "node_modules/@hapi/catbox-object": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@hapi/catbox-object/-/catbox-object-3.0.1.tgz",
"integrity": "sha512-3w6E2DXtjWbmLYi4WcFUOor5jgrXN4PWhDrMrXKP/cEsFSfVSRJ0FhY2PXrhrUHwcllfKezYafWU3tQ5+8RO1w==",
- "requires": {
+ "dependencies": {
"@hapi/boom": "^10.0.1",
"@hapi/hoek": "^11.0.2"
- },
+ }
+ },
+ "node_modules/@hapi/catbox/node_modules/@hapi/validate": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/validate/-/validate-2.0.1.tgz",
+ "integrity": "sha512-NZmXRnrSLK8MQ9y/CMqE9WSspgB9xA41/LlYR0k967aSZebWr4yNrpxIbov12ICwKy4APSlWXZga9jN5p6puPA==",
"dependencies": {
- "@hapi/boom": {
- "version": "10.0.1",
- "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-10.0.1.tgz",
- "integrity": "sha512-ERcCZaEjdH3OgSJlyjVk8pHIFeus91CjKP3v+MpgBNp5IvGzP2l/bRiD78nqYcKPaZdbKkK5vDBVPd2ohHBlsA==",
- "requires": {
- "@hapi/hoek": "^11.0.2"
- }
- },
- "@hapi/hoek": {
- "version": "11.0.2",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-11.0.2.tgz",
- "integrity": "sha512-aKmlCO57XFZ26wso4rJsW4oTUnrgTFw2jh3io7CAtO9w4UltBNwRXvXIVzzyfkaaLRo3nluP/19msA8vDUUuKw=="
- }
+ "@hapi/hoek": "^11.0.2",
+ "@hapi/topo": "^6.0.1"
}
},
- "@hapi/content": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/@hapi/content/-/content-5.0.2.tgz",
- "integrity": "sha512-mre4dl1ygd4ZyOH3tiYBrOUBzV7Pu/EOs8VLGf58vtOEECWed8Uuw6B4iR9AN/8uQt42tB04qpVaMyoMQh0oMw==",
- "requires": {
- "@hapi/boom": "9.x.x"
+ "node_modules/@hapi/content": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/@hapi/content/-/content-6.0.0.tgz",
+ "integrity": "sha512-CEhs7j+H0iQffKfe5Htdak5LBOz/Qc8TRh51cF+BFv0qnuph3Em4pjGVzJMkI2gfTDdlJKWJISGWS1rK34POGA==",
+ "dependencies": {
+ "@hapi/boom": "^10.0.0"
}
},
- "@hapi/cryptiles": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/@hapi/cryptiles/-/cryptiles-5.1.0.tgz",
- "integrity": "sha512-fo9+d1Ba5/FIoMySfMqPBR/7Pa29J2RsiPrl7bkwo5W5o+AN1dAYQRi4SPrPwwVxVGKjgLOEWrsvt1BonJSfLA==",
- "requires": {
- "@hapi/boom": "9.x.x"
+ "node_modules/@hapi/cryptiles": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/cryptiles/-/cryptiles-6.0.1.tgz",
+ "integrity": "sha512-9GM9ECEHfR8lk5ASOKG4+4ZsEzFqLfhiryIJ2ISePVB92OHLp/yne4m+zn7z9dgvM98TLpiFebjDFQ0UHcqxXQ==",
+ "dependencies": {
+ "@hapi/boom": "^10.0.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
}
},
- "@hapi/file": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/file/-/file-2.0.0.tgz",
- "integrity": "sha512-WSrlgpvEqgPWkI18kkGELEZfXr0bYLtr16iIN4Krh9sRnzBZN6nnWxHFxtsnP684wueEySBbXPDg/WfA9xJdBQ=="
+ "node_modules/@hapi/file": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@hapi/file/-/file-3.0.0.tgz",
+ "integrity": "sha512-w+lKW+yRrLhJu620jT3y+5g2mHqnKfepreykvdOcl9/6up8GrQQn+l3FRTsjHTKbkbfQFkuksHpdv2EcpKcJ4Q=="
},
- "@hapi/formula": {
+ "node_modules/@hapi/formula": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-2.0.0.tgz",
- "integrity": "sha512-V87P8fv7PI0LH7LiVi8Lkf3x+KCO7pQozXRssAHNXXL9L1K+uyu4XypLXwxqVDKgyQai6qj3/KteNlrqDx4W5A=="
+ "integrity": "sha512-V87P8fv7PI0LH7LiVi8Lkf3x+KCO7pQozXRssAHNXXL9L1K+uyu4XypLXwxqVDKgyQai6qj3/KteNlrqDx4W5A==",
+ "deprecated": "Moved to 'npm install @sideway/formula'"
},
- "@hapi/good": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/good/-/good-9.0.0.tgz",
- "integrity": "sha512-jt6mEzFfY+jzE/IbvNVTTHcqKE9RP609MXKff1Pj4VPCnCSG8UVUtTdr1nM6UFN02NvntqShlpeZi4o+RgN35g==",
- "requires": {
- "@hapi/hoek": "9.x.x",
- "@hapi/joi": "17.x.x",
- "@hapi/oppsy": "3.x.x",
- "pumpify": "1.x.x"
- },
- "dependencies": {
- "@hapi/address": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/@hapi/address/-/address-4.0.1.tgz",
- "integrity": "sha512-0oEP5UiyV4f3d6cBL8F3Z5S7iWSX39Knnl0lY8i+6gfmmIBj44JCBNtcMgwyS+5v7j3VYavNay0NFHDS+UGQcw==",
- "requires": {
- "@hapi/hoek": "^9.0.0"
- }
- },
- "@hapi/formula": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-2.0.0.tgz",
- "integrity": "sha512-V87P8fv7PI0LH7LiVi8Lkf3x+KCO7pQozXRssAHNXXL9L1K+uyu4XypLXwxqVDKgyQai6qj3/KteNlrqDx4W5A=="
- },
- "@hapi/hoek": {
- "version": "9.0.4",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.4.tgz",
- "integrity": "sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw=="
- },
- "@hapi/joi": {
- "version": "17.1.1",
- "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-17.1.1.tgz",
- "integrity": "sha512-p4DKeZAoeZW4g3u7ZeRo+vCDuSDgSvtsB/NpfjXEHTUjSeINAi/RrVOWiVQ1isaoLzMvFEhe8n5065mQq1AdQg==",
- "requires": {
- "@hapi/address": "^4.0.1",
- "@hapi/formula": "^2.0.0",
- "@hapi/hoek": "^9.0.0",
- "@hapi/pinpoint": "^2.0.0",
- "@hapi/topo": "^5.0.0"
- }
- },
- "@hapi/pinpoint": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.0.tgz",
- "integrity": "sha512-vzXR5MY7n4XeIvLpfl3HtE3coZYO4raKXW766R6DZw/6aLqR26iuZ109K7a0NtF2Db0jxqh7xz2AxkUwpUFybw=="
- },
- "@hapi/topo": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz",
- "integrity": "sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==",
- "requires": {
- "@hapi/hoek": "^9.0.0"
- }
- }
+ "node_modules/@hapi/hapi": {
+ "version": "21.3.3",
+ "resolved": "https://registry.npmjs.org/@hapi/hapi/-/hapi-21.3.3.tgz",
+ "integrity": "sha512-6pgwWVl/aSKSNVn86n+mWa06jRqCAKi2adZp/Hti19A0u5x3/6eiKz8UTBPMzfrdGf9WcrYbFBYzWr/qd2s28g==",
+ "dependencies": {
+ "@hapi/accept": "^6.0.1",
+ "@hapi/ammo": "^6.0.1",
+ "@hapi/boom": "^10.0.1",
+ "@hapi/bounce": "^3.0.1",
+ "@hapi/call": "^9.0.1",
+ "@hapi/catbox": "^12.1.1",
+ "@hapi/catbox-memory": "^6.0.1",
+ "@hapi/heavy": "^8.0.1",
+ "@hapi/hoek": "^11.0.2",
+ "@hapi/mimos": "^7.0.1",
+ "@hapi/podium": "^5.0.1",
+ "@hapi/shot": "^6.0.1",
+ "@hapi/somever": "^4.1.1",
+ "@hapi/statehood": "^8.1.1",
+ "@hapi/subtext": "^8.1.0",
+ "@hapi/teamwork": "^6.0.0",
+ "@hapi/topo": "^6.0.1",
+ "@hapi/validate": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=14.15.0"
+ }
+ },
+ "node_modules/@hapi/hapi/node_modules/@hapi/validate": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/validate/-/validate-2.0.1.tgz",
+ "integrity": "sha512-NZmXRnrSLK8MQ9y/CMqE9WSspgB9xA41/LlYR0k967aSZebWr4yNrpxIbov12ICwKy4APSlWXZga9jN5p6puPA==",
+ "dependencies": {
+ "@hapi/hoek": "^11.0.2",
+ "@hapi/topo": "^6.0.1"
}
},
- "@hapi/good-console": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/good-console/-/good-console-9.0.0.tgz",
- "integrity": "sha512-f0+eFyKGfagfCvyjFm3C2vFmL+4/fsSJ6bgf6LbBf3GV918hZAl40RUCRyiPKdYmEoTAKcq++Ti9xe1oOVDKdA==",
- "requires": {
- "@hapi/hoek": "9.x.x",
- "@hapi/joi": "17.x.x",
- "json-stringify-safe": "5.x.x",
- "moment": "2.x.x"
- },
- "dependencies": {
- "@hapi/address": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/@hapi/address/-/address-4.0.1.tgz",
- "integrity": "sha512-0oEP5UiyV4f3d6cBL8F3Z5S7iWSX39Knnl0lY8i+6gfmmIBj44JCBNtcMgwyS+5v7j3VYavNay0NFHDS+UGQcw==",
- "requires": {
- "@hapi/hoek": "^9.0.0"
- }
- },
- "@hapi/formula": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-2.0.0.tgz",
- "integrity": "sha512-V87P8fv7PI0LH7LiVi8Lkf3x+KCO7pQozXRssAHNXXL9L1K+uyu4XypLXwxqVDKgyQai6qj3/KteNlrqDx4W5A=="
- },
- "@hapi/hoek": {
- "version": "9.0.4",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.4.tgz",
- "integrity": "sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw=="
- },
- "@hapi/joi": {
- "version": "17.1.1",
- "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-17.1.1.tgz",
- "integrity": "sha512-p4DKeZAoeZW4g3u7ZeRo+vCDuSDgSvtsB/NpfjXEHTUjSeINAi/RrVOWiVQ1isaoLzMvFEhe8n5065mQq1AdQg==",
- "requires": {
- "@hapi/address": "^4.0.1",
- "@hapi/formula": "^2.0.0",
- "@hapi/hoek": "^9.0.0",
- "@hapi/pinpoint": "^2.0.0",
- "@hapi/topo": "^5.0.0"
- }
- },
- "@hapi/pinpoint": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.0.tgz",
- "integrity": "sha512-vzXR5MY7n4XeIvLpfl3HtE3coZYO4raKXW766R6DZw/6aLqR26iuZ109K7a0NtF2Db0jxqh7xz2AxkUwpUFybw=="
- },
- "@hapi/topo": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz",
- "integrity": "sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==",
- "requires": {
- "@hapi/hoek": "^9.0.0"
- }
- }
+ "node_modules/@hapi/heavy": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/heavy/-/heavy-8.0.1.tgz",
+ "integrity": "sha512-gBD/NANosNCOp6RsYTsjo2vhr5eYA3BEuogk6cxY0QdhllkkTaJFYtTXv46xd6qhBVMbMMqcSdtqey+UQU3//w==",
+ "dependencies": {
+ "@hapi/boom": "^10.0.1",
+ "@hapi/hoek": "^11.0.2",
+ "@hapi/validate": "^2.0.1"
}
},
- "@hapi/good-squeeze": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/good-squeeze/-/good-squeeze-6.0.0.tgz",
- "integrity": "sha512-UgHAF9Lm8fJPzgf2HymtowOwNc1+IL+p08YTVR+XA4d8nmyE1t9x3RLA4riqldnOKHkVqGakJ1jGqUG7jk77Cg==",
- "requires": {
- "@hapi/hoek": "9.x.x",
- "fast-safe-stringify": "2.x.x"
- },
+ "node_modules/@hapi/heavy/node_modules/@hapi/validate": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/validate/-/validate-2.0.1.tgz",
+ "integrity": "sha512-NZmXRnrSLK8MQ9y/CMqE9WSspgB9xA41/LlYR0k967aSZebWr4yNrpxIbov12ICwKy4APSlWXZga9jN5p6puPA==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.0.4",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.4.tgz",
- "integrity": "sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw=="
- }
+ "@hapi/hoek": "^11.0.2",
+ "@hapi/topo": "^6.0.1"
}
},
- "@hapi/hapi": {
- "version": "20.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hapi/-/hapi-20.3.0.tgz",
- "integrity": "sha512-zvPSRvaQyF3S6Nev9aiAzko2/hIFZmNSJNcs07qdVaVAvj8dGJSV4fVUuQSnufYJAGiSau+U5LxMLhx79se5WA==",
- "requires": {
- "@hapi/accept": "^5.0.1",
- "@hapi/ammo": "^5.0.1",
- "@hapi/boom": "^9.1.0",
- "@hapi/bounce": "^2.0.0",
- "@hapi/call": "^8.0.0",
- "@hapi/catbox": "^11.1.1",
- "@hapi/catbox-memory": "^5.0.0",
- "@hapi/heavy": "^7.0.1",
- "@hapi/hoek": "^9.0.4",
- "@hapi/mimos": "^6.0.0",
- "@hapi/podium": "^4.1.1",
- "@hapi/shot": "^5.0.5",
- "@hapi/somever": "^3.0.0",
- "@hapi/statehood": "^7.0.3",
- "@hapi/subtext": "^7.1.0",
- "@hapi/teamwork": "^5.1.0",
- "@hapi/topo": "^5.0.0",
- "@hapi/validate": "^1.1.1"
- },
- "dependencies": {
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- },
- "@hapi/topo": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
- "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
- "requires": {
- "@hapi/hoek": "^9.0.0"
- }
- }
- }
+ "node_modules/@hapi/hoek": {
+ "version": "11.0.4",
+ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-11.0.4.tgz",
+ "integrity": "sha512-PnsP5d4q7289pS2T2EgGz147BFJ2Jpb4yrEdkpz2IhgEUzos1S7HTl7ezWh1yfYzYlj89KzLdCRkqsP6SIryeQ=="
},
- "@hapi/heavy": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/@hapi/heavy/-/heavy-7.0.1.tgz",
- "integrity": "sha512-vJ/vzRQ13MtRzz6Qd4zRHWS3FaUc/5uivV2TIuExGTM9Qk+7Zzqj0e2G7EpE6KztO9SalTbiIkTh7qFKj/33cA==",
- "requires": {
- "@hapi/boom": "9.x.x",
- "@hapi/hoek": "9.x.x",
- "@hapi/validate": "1.x.x"
- },
+ "node_modules/@hapi/inert": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/@hapi/inert/-/inert-7.1.0.tgz",
+ "integrity": "sha512-5X+cl/Ozm0U9uPGGX1dSKhnhTQIf161bH/kkTN9OBVAZKFG+nrj8j/NMj6S1zBBZWmQrkVRNPfCUGrXzB4fCFQ==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- }
+ "@hapi/ammo": "^6.0.1",
+ "@hapi/boom": "^10.0.1",
+ "@hapi/bounce": "^3.0.1",
+ "@hapi/hoek": "^11.0.2",
+ "@hapi/validate": "^2.0.1",
+ "lru-cache": "^7.14.1"
}
},
- "@hapi/hoek": {
- "version": "8.3.2",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.3.2.tgz",
- "integrity": "sha512-NP5SG4bzix+EtSMtcudp8TvI0lB46mXNo8uFpTDw6tqxGx4z5yx+giIunEFA0Z7oUO4DuWrOJV9xqR2tJVEdyA=="
- },
- "@hapi/inert": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/@hapi/inert/-/inert-6.0.1.tgz",
- "integrity": "sha512-oLxAmtWni3nH4INU2gcXFnHBw0GhHYF3HR71hAWrPc91dq+iFYGfawfaMbonwGr5DkzFiGe8Ir5sZAt2AqeINA==",
- "requires": {
- "@hapi/ammo": "5.x.x",
- "@hapi/boom": "9.x.x",
- "@hapi/bounce": "2.x.x",
- "@hapi/hoek": "9.x.x",
- "@hapi/joi": "17.x.x",
- "lru-cache": "5.x.x"
- },
+ "node_modules/@hapi/inert/node_modules/@hapi/validate": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/validate/-/validate-2.0.1.tgz",
+ "integrity": "sha512-NZmXRnrSLK8MQ9y/CMqE9WSspgB9xA41/LlYR0k967aSZebWr4yNrpxIbov12ICwKy4APSlWXZga9jN5p6puPA==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.0.4",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.4.tgz",
- "integrity": "sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw=="
- },
- "lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "requires": {
- "yallist": "^3.0.2"
- }
- },
- "yallist": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
- "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
- }
+ "@hapi/hoek": "^11.0.2",
+ "@hapi/topo": "^6.0.1"
}
},
- "@hapi/iron": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/iron/-/iron-6.0.0.tgz",
- "integrity": "sha512-zvGvWDufiTGpTJPG1Y/McN8UqWBu0k/xs/7l++HVU535NLHXsHhy54cfEMdW7EjwKfbBfM9Xy25FmTiobb7Hvw==",
- "requires": {
- "@hapi/b64": "5.x.x",
- "@hapi/boom": "9.x.x",
- "@hapi/bourne": "2.x.x",
- "@hapi/cryptiles": "5.x.x",
- "@hapi/hoek": "9.x.x"
- },
- "dependencies": {
- "@hapi/bourne": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.1.0.tgz",
- "integrity": "sha512-i1BpaNDVLJdRBEKeJWkVO6tYX6DMFBuwMhSuWqLsY4ufeTKGVuV5rBsUhxPayXqnnWHgXUAmWK16H/ykO5Wj4Q=="
- },
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- }
+ "node_modules/@hapi/iron": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/iron/-/iron-7.0.1.tgz",
+ "integrity": "sha512-tEZnrOujKpS6jLKliyWBl3A9PaE+ppuL/+gkbyPPDb/l2KSKQyH4lhMkVb+sBhwN+qaxxlig01JRqB8dk/mPxQ==",
+ "dependencies": {
+ "@hapi/b64": "^6.0.1",
+ "@hapi/boom": "^10.0.1",
+ "@hapi/bourne": "^3.0.0",
+ "@hapi/cryptiles": "^6.0.1",
+ "@hapi/hoek": "^11.0.2"
}
},
- "@hapi/joi": {
+ "node_modules/@hapi/joi": {
"version": "17.1.1",
"resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-17.1.1.tgz",
"integrity": "sha512-p4DKeZAoeZW4g3u7ZeRo+vCDuSDgSvtsB/NpfjXEHTUjSeINAi/RrVOWiVQ1isaoLzMvFEhe8n5065mQq1AdQg==",
- "requires": {
+ "deprecated": "Switch to 'npm install joi'",
+ "dependencies": {
"@hapi/address": "^4.0.1",
"@hapi/formula": "^2.0.0",
"@hapi/hoek": "^9.0.0",
"@hapi/pinpoint": "^2.0.0",
"@hapi/topo": "^5.0.0"
- },
+ }
+ },
+ "node_modules/@hapi/joi/node_modules/@hapi/hoek": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
+ "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
+ },
+ "node_modules/@hapi/joi/node_modules/@hapi/topo": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
+ "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
"dependencies": {
- "@hapi/address": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/@hapi/address/-/address-4.0.1.tgz",
- "integrity": "sha512-0oEP5UiyV4f3d6cBL8F3Z5S7iWSX39Knnl0lY8i+6gfmmIBj44JCBNtcMgwyS+5v7j3VYavNay0NFHDS+UGQcw==",
- "requires": {
- "@hapi/hoek": "^9.0.0"
- }
- },
- "@hapi/hoek": {
- "version": "9.0.4",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.4.tgz",
- "integrity": "sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw=="
- },
- "@hapi/topo": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz",
- "integrity": "sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==",
- "requires": {
- "@hapi/hoek": "^9.0.0"
- }
- }
+ "@hapi/hoek": "^9.0.0"
}
},
- "@hapi/jwt": {
+ "node_modules/@hapi/jwt": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@hapi/jwt/-/jwt-3.2.0.tgz",
"integrity": "sha512-2EU5zdr0petG63J2RHiagGByA1Qr6qzxMmrJJ3/0cm78be1Lq4vi038YgKJvbBSxSboIp5SWGZdYB6+CJlqEoQ==",
- "requires": {
+ "dependencies": {
"@hapi/b64": "^6.0.0",
"@hapi/boom": "^10.0.0",
"@hapi/bounce": "^3.0.0",
@@ -866,1014 +1030,572 @@
"@hapi/wreck": "^18.0.0",
"ecdsa-sig-formatter": "^1.0.0",
"joi": "^17.2.1"
- },
+ }
+ },
+ "node_modules/@hapi/jwt/node_modules/@hapi/hoek": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-10.0.1.tgz",
+ "integrity": "sha512-CvlW7jmOhWzuqOqiJQ3rQVLMcREh0eel4IBnxDx2FAcK8g7qoJRQK4L1CPBASoCY6y8e6zuCy3f2g+HWdkzcMw=="
+ },
+ "node_modules/@hapi/mimos": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/mimos/-/mimos-7.0.1.tgz",
+ "integrity": "sha512-b79V+BrG0gJ9zcRx1VGcCI6r6GEzzZUgiGEJVoq5gwzuB2Ig9Cax8dUuBauQCFKvl2YWSWyOc8mZ8HDaJOtkew==",
"dependencies": {
- "@hapi/b64": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/@hapi/b64/-/b64-6.0.1.tgz",
- "integrity": "sha512-ZvjX4JQReUmBheeCq+S9YavcnMMHWqx3S0jHNXWIM1kQDxB9cyfSycpVvjfrKcIS8Mh5N3hmu/YKo4Iag9g2Kw==",
- "requires": {
- "@hapi/hoek": "^11.0.2"
- },
- "dependencies": {
- "@hapi/hoek": {
- "version": "11.0.2",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-11.0.2.tgz",
- "integrity": "sha512-aKmlCO57XFZ26wso4rJsW4oTUnrgTFw2jh3io7CAtO9w4UltBNwRXvXIVzzyfkaaLRo3nluP/19msA8vDUUuKw=="
- }
- }
- },
- "@hapi/boom": {
- "version": "10.0.1",
- "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-10.0.1.tgz",
- "integrity": "sha512-ERcCZaEjdH3OgSJlyjVk8pHIFeus91CjKP3v+MpgBNp5IvGzP2l/bRiD78nqYcKPaZdbKkK5vDBVPd2ohHBlsA==",
- "requires": {
- "@hapi/hoek": "^11.0.2"
- },
- "dependencies": {
- "@hapi/hoek": {
- "version": "11.0.2",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-11.0.2.tgz",
- "integrity": "sha512-aKmlCO57XFZ26wso4rJsW4oTUnrgTFw2jh3io7CAtO9w4UltBNwRXvXIVzzyfkaaLRo3nluP/19msA8vDUUuKw=="
- }
- }
- },
- "@hapi/bounce": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@hapi/bounce/-/bounce-3.0.1.tgz",
- "integrity": "sha512-G+/Pp9c1Ha4FDP+3Sy/Xwg2O4Ahaw3lIZFSX+BL4uWi64CmiETuZPxhKDUD4xBMOUZbBlzvO8HjiK8ePnhBadA==",
- "requires": {
- "@hapi/boom": "^10.0.1",
- "@hapi/hoek": "^11.0.2"
- },
- "dependencies": {
- "@hapi/hoek": {
- "version": "11.0.2",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-11.0.2.tgz",
- "integrity": "sha512-aKmlCO57XFZ26wso4rJsW4oTUnrgTFw2jh3io7CAtO9w4UltBNwRXvXIVzzyfkaaLRo3nluP/19msA8vDUUuKw=="
- }
- }
- },
- "@hapi/bourne": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-3.0.0.tgz",
- "integrity": "sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w=="
- },
- "@hapi/cryptiles": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/@hapi/cryptiles/-/cryptiles-6.0.1.tgz",
- "integrity": "sha512-9GM9ECEHfR8lk5ASOKG4+4ZsEzFqLfhiryIJ2ISePVB92OHLp/yne4m+zn7z9dgvM98TLpiFebjDFQ0UHcqxXQ==",
- "requires": {
- "@hapi/boom": "^10.0.1"
- }
- },
- "@hapi/hoek": {
- "version": "10.0.1",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-10.0.1.tgz",
- "integrity": "sha512-CvlW7jmOhWzuqOqiJQ3rQVLMcREh0eel4IBnxDx2FAcK8g7qoJRQK4L1CPBASoCY6y8e6zuCy3f2g+HWdkzcMw=="
- },
- "@hapi/wreck": {
- "version": "18.0.1",
- "resolved": "https://registry.npmjs.org/@hapi/wreck/-/wreck-18.0.1.tgz",
- "integrity": "sha512-OLHER70+rZxvDl75xq3xXOfd3e8XIvz8fWY0dqg92UvhZ29zo24vQgfqgHSYhB5ZiuFpSLeriOisAlxAo/1jWg==",
- "requires": {
- "@hapi/boom": "^10.0.1",
- "@hapi/bourne": "^3.0.0",
- "@hapi/hoek": "^11.0.2"
- },
- "dependencies": {
- "@hapi/hoek": {
- "version": "11.0.2",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-11.0.2.tgz",
- "integrity": "sha512-aKmlCO57XFZ26wso4rJsW4oTUnrgTFw2jh3io7CAtO9w4UltBNwRXvXIVzzyfkaaLRo3nluP/19msA8vDUUuKw=="
- }
- }
- }
+ "@hapi/hoek": "^11.0.2",
+ "mime-db": "^1.52.0"
}
},
- "@hapi/mimos": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/mimos/-/mimos-6.0.0.tgz",
- "integrity": "sha512-Op/67tr1I+JafN3R3XN5DucVSxKRT/Tc+tUszDwENoNpolxeXkhrJ2Czt6B6AAqrespHoivhgZBWYSuANN9QXg==",
- "requires": {
- "@hapi/hoek": "9.x.x",
- "mime-db": "1.x.x"
+ "node_modules/@hapi/nigel": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/nigel/-/nigel-5.0.1.tgz",
+ "integrity": "sha512-uv3dtYuB4IsNaha+tigWmN8mQw/O9Qzl5U26Gm4ZcJVtDdB1AVJOwX3X5wOX+A07qzpEZnOMBAm8jjSqGsU6Nw==",
+ "dependencies": {
+ "@hapi/hoek": "^11.0.2",
+ "@hapi/vise": "^5.0.1"
},
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@hapi/pez": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/@hapi/pez/-/pez-6.1.0.tgz",
+ "integrity": "sha512-+FE3sFPYuXCpuVeHQ/Qag1b45clR2o54QoonE/gKHv9gukxQ8oJJZPR7o3/ydDTK6racnCJXxOyT1T93FCJMIg==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- }
+ "@hapi/b64": "^6.0.1",
+ "@hapi/boom": "^10.0.1",
+ "@hapi/content": "^6.0.0",
+ "@hapi/hoek": "^11.0.2",
+ "@hapi/nigel": "^5.0.1"
}
},
- "@hapi/nigel": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/@hapi/nigel/-/nigel-4.0.2.tgz",
- "integrity": "sha512-ht2KoEsDW22BxQOEkLEJaqfpoKPXxi7tvabXy7B/77eFtOyG5ZEstfZwxHQcqAiZhp58Ae5vkhEqI03kawkYNw==",
- "requires": {
- "@hapi/hoek": "^9.0.4",
- "@hapi/vise": "^4.0.0"
- },
+ "node_modules/@hapi/pinpoint": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.1.tgz",
+ "integrity": "sha512-EKQmr16tM8s16vTT3cA5L0kZZcTMU5DUOZTuvpnY738m+jyP3JIUj+Mm1xc1rsLkGBQ/gVnfKYPwOmPg1tUR4Q=="
+ },
+ "node_modules/@hapi/podium": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/podium/-/podium-5.0.1.tgz",
+ "integrity": "sha512-eznFTw6rdBhAijXFIlBOMJJd+lXTvqbrBIS4Iu80r2KTVIo4g+7fLy4NKp/8+UnSt5Ox6mJtAlKBU/Sf5080TQ==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- }
+ "@hapi/hoek": "^11.0.2",
+ "@hapi/teamwork": "^6.0.0",
+ "@hapi/validate": "^2.0.1"
}
},
- "@hapi/oppsy": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/oppsy/-/oppsy-3.0.0.tgz",
- "integrity": "sha512-0kfUEAqIi21GzFVK2snMO07znMEBiXb+/pOx1dmgOO9TuvFstcfmHU5i56aDfiFP2DM5WzQCU2UWc2gK1lMDhQ==",
- "requires": {
- "@hapi/hoek": "9.x.x"
- },
+ "node_modules/@hapi/podium/node_modules/@hapi/validate": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/validate/-/validate-2.0.1.tgz",
+ "integrity": "sha512-NZmXRnrSLK8MQ9y/CMqE9WSspgB9xA41/LlYR0k967aSZebWr4yNrpxIbov12ICwKy4APSlWXZga9jN5p6puPA==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.0.4",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.4.tgz",
- "integrity": "sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw=="
- }
+ "@hapi/hoek": "^11.0.2",
+ "@hapi/topo": "^6.0.1"
}
},
- "@hapi/pez": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/@hapi/pez/-/pez-5.1.0.tgz",
- "integrity": "sha512-YfB0btnkLB3lb6Ry/1KifnMPBm5ZPfaAHWFskzOMAgDgXgcBgA+zjpIynyEiBfWEz22DBT8o1e2tAaBdlt8zbw==",
- "requires": {
- "@hapi/b64": "5.x.x",
- "@hapi/boom": "9.x.x",
- "@hapi/content": "^5.0.2",
- "@hapi/hoek": "9.x.x",
- "@hapi/nigel": "4.x.x"
- },
+ "node_modules/@hapi/shot": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/shot/-/shot-6.0.1.tgz",
+ "integrity": "sha512-s5ynMKZXYoDd3dqPw5YTvOR/vjHvMTxc388+0qL0jZZP1+uwXuUD32o9DuuuLsmTlyXCWi02BJl1pBpwRuUrNA==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- }
+ "@hapi/hoek": "^11.0.2",
+ "@hapi/validate": "^2.0.1"
}
},
- "@hapi/pinpoint": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.0.tgz",
- "integrity": "sha512-vzXR5MY7n4XeIvLpfl3HtE3coZYO4raKXW766R6DZw/6aLqR26iuZ109K7a0NtF2Db0jxqh7xz2AxkUwpUFybw=="
- },
- "@hapi/podium": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/@hapi/podium/-/podium-4.1.3.tgz",
- "integrity": "sha512-ljsKGQzLkFqnQxE7qeanvgGj4dejnciErYd30dbrYzUOF/FyS/DOF97qcrT3bhoVwCYmxa6PEMhxfCPlnUcD2g==",
- "requires": {
- "@hapi/hoek": "9.x.x",
- "@hapi/teamwork": "5.x.x",
- "@hapi/validate": "1.x.x"
- },
+ "node_modules/@hapi/shot/node_modules/@hapi/validate": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/validate/-/validate-2.0.1.tgz",
+ "integrity": "sha512-NZmXRnrSLK8MQ9y/CMqE9WSspgB9xA41/LlYR0k967aSZebWr4yNrpxIbov12ICwKy4APSlWXZga9jN5p6puPA==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- }
+ "@hapi/hoek": "^11.0.2",
+ "@hapi/topo": "^6.0.1"
}
},
- "@hapi/shot": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/@hapi/shot/-/shot-5.0.5.tgz",
- "integrity": "sha512-x5AMSZ5+j+Paa8KdfCoKh+klB78otxF+vcJR/IoN91Vo2e5ulXIW6HUsFTCU+4W6P/Etaip9nmdAx2zWDimB2A==",
- "requires": {
- "@hapi/hoek": "9.x.x",
- "@hapi/validate": "1.x.x"
- },
+ "node_modules/@hapi/somever": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/@hapi/somever/-/somever-4.1.1.tgz",
+ "integrity": "sha512-lt3QQiDDOVRatS0ionFDNrDIv4eXz58IibQaZQDOg4DqqdNme8oa0iPWcE0+hkq/KTeBCPtEOjDOBKBKwDumVg==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- }
+ "@hapi/bounce": "^3.0.1",
+ "@hapi/hoek": "^11.0.2"
}
},
- "@hapi/somever": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@hapi/somever/-/somever-3.0.1.tgz",
- "integrity": "sha512-4ZTSN3YAHtgpY/M4GOtHUXgi6uZtG9nEZfNI6QrArhK0XN/RDVgijlb9kOmXwCR5VclDSkBul9FBvhSuKXx9+w==",
- "requires": {
- "@hapi/bounce": "2.x.x",
- "@hapi/hoek": "9.x.x"
- },
+ "node_modules/@hapi/statehood": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/@hapi/statehood/-/statehood-8.1.1.tgz",
+ "integrity": "sha512-YbK7PSVUA59NArAW5Np0tKRoIZ5VNYUicOk7uJmWZF6XyH5gGL+k62w77SIJb0AoAJ0QdGQMCQ/WOGL1S3Ydow==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- }
+ "@hapi/boom": "^10.0.1",
+ "@hapi/bounce": "^3.0.1",
+ "@hapi/bourne": "^3.0.0",
+ "@hapi/cryptiles": "^6.0.1",
+ "@hapi/hoek": "^11.0.2",
+ "@hapi/iron": "^7.0.1",
+ "@hapi/validate": "^2.0.1"
}
},
- "@hapi/statehood": {
- "version": "7.0.4",
- "resolved": "https://registry.npmjs.org/@hapi/statehood/-/statehood-7.0.4.tgz",
- "integrity": "sha512-Fia6atroOVmc5+2bNOxF6Zv9vpbNAjEXNcUbWXavDqhnJDlchwUUwKS5LCi5mGtCTxRhUKKHwuxuBZJkmLZ7fw==",
- "requires": {
- "@hapi/boom": "9.x.x",
- "@hapi/bounce": "2.x.x",
- "@hapi/bourne": "2.x.x",
- "@hapi/cryptiles": "5.x.x",
- "@hapi/hoek": "9.x.x",
- "@hapi/iron": "6.x.x",
- "@hapi/validate": "1.x.x"
- },
+ "node_modules/@hapi/statehood/node_modules/@hapi/validate": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/validate/-/validate-2.0.1.tgz",
+ "integrity": "sha512-NZmXRnrSLK8MQ9y/CMqE9WSspgB9xA41/LlYR0k967aSZebWr4yNrpxIbov12ICwKy4APSlWXZga9jN5p6puPA==",
"dependencies": {
- "@hapi/bourne": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.1.0.tgz",
- "integrity": "sha512-i1BpaNDVLJdRBEKeJWkVO6tYX6DMFBuwMhSuWqLsY4ufeTKGVuV5rBsUhxPayXqnnWHgXUAmWK16H/ykO5Wj4Q=="
- },
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- }
+ "@hapi/hoek": "^11.0.2",
+ "@hapi/topo": "^6.0.1"
}
},
- "@hapi/subtext": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@hapi/subtext/-/subtext-7.1.0.tgz",
- "integrity": "sha512-n94cU6hlvsNRIpXaROzBNEJGwxC+HA69q769pChzej84On8vsU14guHDub7Pphr/pqn5b93zV3IkMPDU5AUiXA==",
- "requires": {
- "@hapi/boom": "9.x.x",
- "@hapi/bourne": "2.x.x",
- "@hapi/content": "^5.0.2",
- "@hapi/file": "2.x.x",
- "@hapi/hoek": "9.x.x",
- "@hapi/pez": "^5.1.0",
- "@hapi/wreck": "17.x.x"
- },
+ "node_modules/@hapi/subtext": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@hapi/subtext/-/subtext-8.1.0.tgz",
+ "integrity": "sha512-PyaN4oSMtqPjjVxLny1k0iYg4+fwGusIhaom9B2StinBclHs7v46mIW706Y+Wo21lcgulGyXbQrmT/w4dus6ww==",
"dependencies": {
- "@hapi/bourne": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.1.0.tgz",
- "integrity": "sha512-i1BpaNDVLJdRBEKeJWkVO6tYX6DMFBuwMhSuWqLsY4ufeTKGVuV5rBsUhxPayXqnnWHgXUAmWK16H/ykO5Wj4Q=="
- },
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- }
+ "@hapi/boom": "^10.0.1",
+ "@hapi/bourne": "^3.0.0",
+ "@hapi/content": "^6.0.0",
+ "@hapi/file": "^3.0.0",
+ "@hapi/hoek": "^11.0.2",
+ "@hapi/pez": "^6.1.0",
+ "@hapi/wreck": "^18.0.1"
}
},
- "@hapi/teamwork": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/@hapi/teamwork/-/teamwork-5.1.1.tgz",
- "integrity": "sha512-1oPx9AE5TIv+V6Ih54RP9lTZBso3rP8j4Xhb6iSVwPXtAM+sDopl5TFMv5Paw73UnpZJ9gjcrTE1BXrWt9eQrg=="
+ "node_modules/@hapi/teamwork": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/@hapi/teamwork/-/teamwork-6.0.0.tgz",
+ "integrity": "sha512-05HumSy3LWfXpmJ9cr6HzwhAavrHkJ1ZRCmNE2qJMihdM5YcWreWPfyN0yKT2ZjCM92au3ZkuodjBxOibxM67A==",
+ "engines": {
+ "node": ">=14.0.0"
+ }
},
- "@hapi/topo": {
- "version": "3.1.6",
- "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz",
- "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==",
- "requires": {
- "@hapi/hoek": "^8.3.0"
+ "node_modules/@hapi/topo": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-6.0.2.tgz",
+ "integrity": "sha512-KR3rD5inZbGMrHmgPxsJ9dbi6zEK+C3ZwUwTa+eMwWLz7oijWUTWD2pMSNNYJAU6Qq+65NkxXjqHr/7LM2Xkqg==",
+ "dependencies": {
+ "@hapi/hoek": "^11.0.2"
}
},
- "@hapi/validate": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@hapi/validate/-/validate-1.1.3.tgz",
- "integrity": "sha512-/XMR0N0wjw0Twzq2pQOzPBZlDzkekGcoCtzO314BpIEsbXdYGthQUbxgkGDf4nhk1+IPDAsXqWjMohRQYO06UA==",
- "requires": {
- "@hapi/hoek": "^9.0.0",
- "@hapi/topo": "^5.0.0"
- },
+ "node_modules/@hapi/vise": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/vise/-/vise-5.0.1.tgz",
+ "integrity": "sha512-XZYWzzRtINQLedPYlIkSkUr7m5Ddwlu99V9elh8CSygXstfv3UnWIXT0QD+wmR0VAG34d2Vx3olqcEhRRoTu9A==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- },
- "@hapi/topo": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
- "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
- "requires": {
- "@hapi/hoek": "^9.0.0"
- }
- }
+ "@hapi/hoek": "^11.0.2"
}
},
- "@hapi/vise": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/vise/-/vise-4.0.0.tgz",
- "integrity": "sha512-eYyLkuUiFZTer59h+SGy7hUm+qE9p+UemePTHLlIWppEd+wExn3Df5jO04bFQTm7nleF5V8CtuYQYb+VFpZ6Sg==",
- "requires": {
- "@hapi/hoek": "9.x.x"
- },
+ "node_modules/@hapi/vision": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/@hapi/vision/-/vision-7.0.3.tgz",
+ "integrity": "sha512-1UM3Xej7HZQPaxzWkefvMfcuXoF9R8kIiDTl+Pfdv8f5mJwAv0zIB4R/UvNoQP1+JYgQT+QeUDxcGD8QdIUDyg==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- }
+ "@hapi/boom": "^10.0.1",
+ "@hapi/bounce": "^3.0.1",
+ "@hapi/hoek": "^11.0.2",
+ "@hapi/validate": "^2.0.1"
}
},
- "@hapi/vision": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/vision/-/vision-6.0.0.tgz",
- "integrity": "sha512-NRG87SLS8evCTwAGlVHykmlk1i9z+7TD2pUwoDHRpjwqX/syt0ecrEKMLV/VdMijE9tCAtKIIXt+Myb16tT7Sw==",
- "requires": {
- "@hapi/boom": "9.x.x",
- "@hapi/bounce": "2.x.x",
- "@hapi/hoek": "9.x.x",
- "@hapi/joi": "17.x.x"
- },
+ "node_modules/@hapi/vision/node_modules/@hapi/validate": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/validate/-/validate-2.0.1.tgz",
+ "integrity": "sha512-NZmXRnrSLK8MQ9y/CMqE9WSspgB9xA41/LlYR0k967aSZebWr4yNrpxIbov12ICwKy4APSlWXZga9jN5p6puPA==",
"dependencies": {
- "@hapi/address": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/@hapi/address/-/address-4.0.1.tgz",
- "integrity": "sha512-0oEP5UiyV4f3d6cBL8F3Z5S7iWSX39Knnl0lY8i+6gfmmIBj44JCBNtcMgwyS+5v7j3VYavNay0NFHDS+UGQcw==",
- "requires": {
- "@hapi/hoek": "^9.0.0"
- }
- },
- "@hapi/bounce": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/bounce/-/bounce-2.0.0.tgz",
- "integrity": "sha512-JesW92uyzOOyuzJKjoLHM1ThiOvHPOLDHw01YV8yh5nCso7sDwJho1h0Ad2N+E62bZyz46TG3xhAi/78Gsct6A==",
- "requires": {
- "@hapi/boom": "9.x.x",
- "@hapi/hoek": "9.x.x"
- }
- },
- "@hapi/formula": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-2.0.0.tgz",
- "integrity": "sha512-V87P8fv7PI0LH7LiVi8Lkf3x+KCO7pQozXRssAHNXXL9L1K+uyu4XypLXwxqVDKgyQai6qj3/KteNlrqDx4W5A=="
- },
- "@hapi/hoek": {
- "version": "9.0.4",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.4.tgz",
- "integrity": "sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw=="
- },
- "@hapi/joi": {
- "version": "17.1.1",
- "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-17.1.1.tgz",
- "integrity": "sha512-p4DKeZAoeZW4g3u7ZeRo+vCDuSDgSvtsB/NpfjXEHTUjSeINAi/RrVOWiVQ1isaoLzMvFEhe8n5065mQq1AdQg==",
- "requires": {
- "@hapi/address": "^4.0.1",
- "@hapi/formula": "^2.0.0",
- "@hapi/hoek": "^9.0.0",
- "@hapi/pinpoint": "^2.0.0",
- "@hapi/topo": "^5.0.0"
- }
- },
- "@hapi/pinpoint": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.0.tgz",
- "integrity": "sha512-vzXR5MY7n4XeIvLpfl3HtE3coZYO4raKXW766R6DZw/6aLqR26iuZ109K7a0NtF2Db0jxqh7xz2AxkUwpUFybw=="
- },
- "@hapi/topo": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz",
- "integrity": "sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==",
- "requires": {
- "@hapi/hoek": "^9.0.0"
- }
- }
+ "@hapi/hoek": "^11.0.2",
+ "@hapi/topo": "^6.0.1"
}
},
- "@hapi/wreck": {
- "version": "17.2.0",
- "resolved": "https://registry.npmjs.org/@hapi/wreck/-/wreck-17.2.0.tgz",
- "integrity": "sha512-pJ5kjYoRPYDv+eIuiLQqhGon341fr2bNIYZjuotuPJG/3Ilzr/XtI+JAp0A86E2bYfsS3zBPABuS2ICkaXFT8g==",
- "requires": {
- "@hapi/boom": "9.x.x",
- "@hapi/bourne": "2.x.x",
- "@hapi/hoek": "9.x.x"
- },
+ "node_modules/@hapi/wreck": {
+ "version": "18.0.1",
+ "resolved": "https://registry.npmjs.org/@hapi/wreck/-/wreck-18.0.1.tgz",
+ "integrity": "sha512-OLHER70+rZxvDl75xq3xXOfd3e8XIvz8fWY0dqg92UvhZ29zo24vQgfqgHSYhB5ZiuFpSLeriOisAlxAo/1jWg==",
"dependencies": {
- "@hapi/bourne": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.1.0.tgz",
- "integrity": "sha512-i1BpaNDVLJdRBEKeJWkVO6tYX6DMFBuwMhSuWqLsY4ufeTKGVuV5rBsUhxPayXqnnWHgXUAmWK16H/ykO5Wj4Q=="
- },
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- }
+ "@hapi/boom": "^10.0.1",
+ "@hapi/bourne": "^3.0.0",
+ "@hapi/hoek": "^11.0.2"
}
},
- "@istanbuljs/load-nyc-config": {
+ "node_modules/@istanbuljs/load-nyc-config": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
"integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
"dev": true,
- "requires": {
+ "dependencies": {
"camelcase": "^5.3.1",
"find-up": "^4.1.0",
"get-package-type": "^0.1.0",
"js-yaml": "^3.13.1",
"resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "@istanbuljs/schema": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz",
- "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==",
- "dev": true
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
},
- "@jest/console": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz",
- "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==",
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/console": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz",
+ "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==",
"dev": true,
- "requires": {
- "@jest/types": "^26.0.1",
+ "dependencies": {
+ "@jest/types": "^28.1.3",
+ "@types/node": "*",
"chalk": "^4.0.0",
- "jest-message-util": "^26.0.1",
- "jest-util": "^26.0.1",
+ "jest-message-util": "^28.1.3",
+ "jest-util": "^28.1.3",
"slash": "^3.0.0"
},
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "@jest/core": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.0.1.tgz",
- "integrity": "sha512-Xq3eqYnxsG9SjDC+WLeIgf7/8KU6rddBxH+SCt18gEpOhAGYC/Mq+YbtlNcIdwjnnT+wDseXSbU0e5X84Y4jTQ==",
+ "node_modules/@jest/core": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.3.tgz",
+ "integrity": "sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==",
"dev": true,
- "requires": {
- "@jest/console": "^26.0.1",
- "@jest/reporters": "^26.0.1",
- "@jest/test-result": "^26.0.1",
- "@jest/transform": "^26.0.1",
- "@jest/types": "^26.0.1",
+ "dependencies": {
+ "@jest/console": "^28.1.3",
+ "@jest/reporters": "^28.1.3",
+ "@jest/test-result": "^28.1.3",
+ "@jest/transform": "^28.1.3",
+ "@jest/types": "^28.1.3",
+ "@types/node": "*",
"ansi-escapes": "^4.2.1",
"chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
"exit": "^0.1.2",
- "graceful-fs": "^4.2.4",
- "jest-changed-files": "^26.0.1",
- "jest-config": "^26.0.1",
- "jest-haste-map": "^26.0.1",
- "jest-message-util": "^26.0.1",
- "jest-regex-util": "^26.0.0",
- "jest-resolve": "^26.0.1",
- "jest-resolve-dependencies": "^26.0.1",
- "jest-runner": "^26.0.1",
- "jest-runtime": "^26.0.1",
- "jest-snapshot": "^26.0.1",
- "jest-util": "^26.0.1",
- "jest-validate": "^26.0.1",
- "jest-watcher": "^26.0.1",
- "micromatch": "^4.0.2",
- "p-each-series": "^2.1.0",
+ "graceful-fs": "^4.2.9",
+ "jest-changed-files": "^28.1.3",
+ "jest-config": "^28.1.3",
+ "jest-haste-map": "^28.1.3",
+ "jest-message-util": "^28.1.3",
+ "jest-regex-util": "^28.0.2",
+ "jest-resolve": "^28.1.3",
+ "jest-resolve-dependencies": "^28.1.3",
+ "jest-runner": "^28.1.3",
+ "jest-runtime": "^28.1.3",
+ "jest-snapshot": "^28.1.3",
+ "jest-util": "^28.1.3",
+ "jest-validate": "^28.1.3",
+ "jest-watcher": "^28.1.3",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^28.1.3",
"rimraf": "^3.0.0",
"slash": "^3.0.0",
"strip-ansi": "^6.0.0"
},
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/environment": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz",
+ "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==",
+ "dev": true,
"dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
- "dev": true,
- "requires": {
- "fill-range": "^7.0.1"
- }
- },
- "chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
- "dev": true,
- "requires": {
- "to-regex-range": "^5.0.1"
- }
- },
- "graceful-fs": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
- "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true
- },
- "micromatch": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
- "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
- "dev": true,
- "requires": {
- "braces": "^3.0.1",
- "picomatch": "^2.0.5"
- }
- },
- "rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
- "requires": {
- "glob": "^7.1.3"
- }
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- },
- "to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "requires": {
- "is-number": "^7.0.0"
- }
- }
+ "@jest/fake-timers": "^28.1.3",
+ "@jest/types": "^28.1.3",
+ "@types/node": "*",
+ "jest-mock": "^28.1.3"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+ }
+ },
+ "node_modules/@jest/expect": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz",
+ "integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==",
+ "dev": true,
+ "dependencies": {
+ "expect": "^28.1.3",
+ "jest-snapshot": "^28.1.3"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "@jest/environment": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz",
- "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==",
+ "node_modules/@jest/expect-utils": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz",
+ "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==",
"dev": true,
- "requires": {
- "@jest/fake-timers": "^26.0.1",
- "@jest/types": "^26.0.1",
- "jest-mock": "^26.0.1"
+ "dependencies": {
+ "jest-get-type": "^28.0.2"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "@jest/fake-timers": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz",
- "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==",
+ "node_modules/@jest/fake-timers": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz",
+ "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==",
"dev": true,
- "requires": {
- "@jest/types": "^26.0.1",
- "@sinonjs/fake-timers": "^6.0.1",
- "jest-message-util": "^26.0.1",
- "jest-mock": "^26.0.1",
- "jest-util": "^26.0.1"
+ "dependencies": {
+ "@jest/types": "^28.1.3",
+ "@sinonjs/fake-timers": "^9.1.2",
+ "@types/node": "*",
+ "jest-message-util": "^28.1.3",
+ "jest-mock": "^28.1.3",
+ "jest-util": "^28.1.3"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "@jest/globals": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.0.1.tgz",
- "integrity": "sha512-iuucxOYB7BRCvT+TYBzUqUNuxFX1hqaR6G6IcGgEqkJ5x4htNKo1r7jk1ji9Zj8ZMiMw0oB5NaA7k5Tx6MVssA==",
+ "node_modules/@jest/globals": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz",
+ "integrity": "sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==",
"dev": true,
- "requires": {
- "@jest/environment": "^26.0.1",
- "@jest/types": "^26.0.1",
- "expect": "^26.0.1"
+ "dependencies": {
+ "@jest/environment": "^28.1.3",
+ "@jest/expect": "^28.1.3",
+ "@jest/types": "^28.1.3"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "@jest/reporters": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.0.1.tgz",
- "integrity": "sha512-NWWy9KwRtE1iyG/m7huiFVF9YsYv/e+mbflKRV84WDoJfBqUrNRyDbL/vFxQcYLl8IRqI4P3MgPn386x76Gf2g==",
+ "node_modules/@jest/reporters": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.3.tgz",
+ "integrity": "sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==",
"dev": true,
- "requires": {
+ "dependencies": {
"@bcoe/v8-coverage": "^0.2.3",
- "@jest/console": "^26.0.1",
- "@jest/test-result": "^26.0.1",
- "@jest/transform": "^26.0.1",
- "@jest/types": "^26.0.1",
+ "@jest/console": "^28.1.3",
+ "@jest/test-result": "^28.1.3",
+ "@jest/transform": "^28.1.3",
+ "@jest/types": "^28.1.3",
+ "@jridgewell/trace-mapping": "^0.3.13",
+ "@types/node": "*",
"chalk": "^4.0.0",
"collect-v8-coverage": "^1.0.0",
"exit": "^0.1.2",
- "glob": "^7.1.2",
- "graceful-fs": "^4.2.4",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
"istanbul-lib-coverage": "^3.0.0",
- "istanbul-lib-instrument": "^4.0.0",
+ "istanbul-lib-instrument": "^5.1.0",
"istanbul-lib-report": "^3.0.0",
"istanbul-lib-source-maps": "^4.0.0",
- "istanbul-reports": "^3.0.2",
- "jest-haste-map": "^26.0.1",
- "jest-resolve": "^26.0.1",
- "jest-util": "^26.0.1",
- "jest-worker": "^26.0.0",
- "node-notifier": "^7.0.0",
+ "istanbul-reports": "^3.1.3",
+ "jest-message-util": "^28.1.3",
+ "jest-util": "^28.1.3",
+ "jest-worker": "^28.1.3",
"slash": "^3.0.0",
- "source-map": "^0.6.0",
"string-length": "^4.0.1",
+ "strip-ansi": "^6.0.0",
"terminal-link": "^2.0.0",
- "v8-to-istanbul": "^4.1.3"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "graceful-fs": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
- "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
+ "v8-to-istanbul": "^9.0.1"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
}
}
},
- "@jest/source-map": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.0.0.tgz",
- "integrity": "sha512-S2Z+Aj/7KOSU2TfW0dyzBze7xr95bkm5YXNUqqCek+HE0VbNNSNzrRwfIi5lf7wvzDTSS0/ib8XQ1krFNyYgbQ==",
+ "node_modules/@jest/schemas": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz",
+ "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==",
"dev": true,
- "requires": {
- "callsites": "^3.0.0",
- "graceful-fs": "^4.2.4",
- "source-map": "^0.6.0"
+ "dependencies": {
+ "@sinclair/typebox": "^0.24.1"
},
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+ }
+ },
+ "node_modules/@jest/source-map": {
+ "version": "28.1.2",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.1.2.tgz",
+ "integrity": "sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==",
+ "dev": true,
"dependencies": {
- "graceful-fs": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
- "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
- "dev": true
- }
+ "@jridgewell/trace-mapping": "^0.3.13",
+ "callsites": "^3.0.0",
+ "graceful-fs": "^4.2.9"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "@jest/test-result": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz",
- "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==",
+ "node_modules/@jest/test-result": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz",
+ "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==",
"dev": true,
- "requires": {
- "@jest/console": "^26.0.1",
- "@jest/types": "^26.0.1",
+ "dependencies": {
+ "@jest/console": "^28.1.3",
+ "@jest/types": "^28.1.3",
"@types/istanbul-lib-coverage": "^2.0.0",
"collect-v8-coverage": "^1.0.0"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "@jest/test-sequencer": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.0.1.tgz",
- "integrity": "sha512-ssga8XlwfP8YjbDcmVhwNlrmblddMfgUeAkWIXts1V22equp2GMIHxm7cyeD5Q/B0ZgKPK/tngt45sH99yLLGg==",
+ "node_modules/@jest/test-sequencer": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz",
+ "integrity": "sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==",
"dev": true,
- "requires": {
- "@jest/test-result": "^26.0.1",
- "graceful-fs": "^4.2.4",
- "jest-haste-map": "^26.0.1",
- "jest-runner": "^26.0.1",
- "jest-runtime": "^26.0.1"
- },
"dependencies": {
- "graceful-fs": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
- "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
- "dev": true
- }
+ "@jest/test-result": "^28.1.3",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^28.1.3",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "@jest/transform": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.0.1.tgz",
- "integrity": "sha512-pPRkVkAQ91drKGbzCfDOoHN838+FSbYaEAvBXvKuWeeRRUD8FjwXkqfUNUZL6Ke48aA/1cqq/Ni7kVMCoqagWA==",
+ "node_modules/@jest/transform": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz",
+ "integrity": "sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==",
"dev": true,
- "requires": {
- "@babel/core": "^7.1.0",
- "@jest/types": "^26.0.1",
- "babel-plugin-istanbul": "^6.0.0",
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@jest/types": "^28.1.3",
+ "@jridgewell/trace-mapping": "^0.3.13",
+ "babel-plugin-istanbul": "^6.1.1",
"chalk": "^4.0.0",
"convert-source-map": "^1.4.0",
"fast-json-stable-stringify": "^2.0.0",
- "graceful-fs": "^4.2.4",
- "jest-haste-map": "^26.0.1",
- "jest-regex-util": "^26.0.0",
- "jest-util": "^26.0.1",
- "micromatch": "^4.0.2",
- "pirates": "^4.0.1",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^28.1.3",
+ "jest-regex-util": "^28.0.2",
+ "jest-util": "^28.1.3",
+ "micromatch": "^4.0.4",
+ "pirates": "^4.0.4",
"slash": "^3.0.0",
- "source-map": "^0.6.1",
- "write-file-atomic": "^3.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
- "dev": true,
- "requires": {
- "fill-range": "^7.0.1"
- }
- },
- "chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
- "dev": true,
- "requires": {
- "to-regex-range": "^5.0.1"
- }
- },
- "graceful-fs": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
- "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true
- },
- "micromatch": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
- "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
- "dev": true,
- "requires": {
- "braces": "^3.0.1",
- "picomatch": "^2.0.5"
- }
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- },
- "to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "requires": {
- "is-number": "^7.0.0"
- }
- },
- "write-file-atomic": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
- "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
- "dev": true,
- "requires": {
- "imurmurhash": "^0.1.4",
- "is-typedarray": "^1.0.0",
- "signal-exit": "^3.0.2",
- "typedarray-to-buffer": "^3.1.5"
- }
- }
+ "write-file-atomic": "^4.0.1"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "@jest/types": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz",
- "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==",
+ "node_modules/@jest/types": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz",
+ "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==",
"dev": true,
- "requires": {
+ "dependencies": {
+ "@jest/schemas": "^28.1.3",
"@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^1.1.1",
- "@types/yargs": "^15.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.8",
"chalk": "^4.0.0"
},
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+ "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
+ "dev": true,
"dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
+ "@jridgewell/set-array": "^1.2.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
}
},
- "@mapbox/node-pre-gyp": {
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.15",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+ "dev": true
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@jsdevtools/ono": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz",
+ "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg=="
+ },
+ "node_modules/@mapbox/node-pre-gyp": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz",
"integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==",
- "requires": {
+ "dependencies": {
"detect-libc": "^2.0.0",
"https-proxy-agent": "^5.0.0",
"make-dir": "^3.1.0",
@@ -1884,1917 +1606,1200 @@
"semver": "^7.3.5",
"tar": "^6.1.11"
},
- "dependencies": {
- "lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "requires": {
- "yallist": "^4.0.0"
- }
- },
- "nopt": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
- "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
- "requires": {
- "abbrev": "1"
- }
- },
- "semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
- "requires": {
- "lru-cache": "^6.0.0"
- }
- }
+ "bin": {
+ "node-pre-gyp": "bin/node-pre-gyp"
}
},
- "@sideway/address": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz",
- "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==",
- "requires": {
- "@hapi/hoek": "^9.0.0"
- },
+ "node_modules/@sideway/address": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
+ "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- }
+ "@hapi/hoek": "^9.0.0"
}
},
- "@sideway/formula": {
+ "node_modules/@sideway/address/node_modules/@hapi/hoek": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
+ "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
+ },
+ "node_modules/@sideway/formula": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
"integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg=="
},
- "@sideway/pinpoint": {
+ "node_modules/@sideway/pinpoint": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
"integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ=="
},
- "@sindresorhus/is": {
- "version": "0.14.0",
- "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
- "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+ "node_modules/@sinclair/typebox": {
+ "version": "0.24.51",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
+ "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==",
"dev": true
},
- "@sinonjs/commons": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.0.tgz",
- "integrity": "sha512-wEj54PfsZ5jGSwMX68G8ZXFawcSglQSXqCftWX3ec8MDUzQdHgcKvw97awHbY0efQEL5iKUOAmmVtoYgmrSG4Q==",
+ "node_modules/@sinonjs/commons": {
+ "version": "1.8.6",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz",
+ "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==",
"dev": true,
- "requires": {
+ "dependencies": {
"type-detect": "4.0.8"
}
},
- "@sinonjs/fake-timers": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz",
- "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==",
+ "node_modules/@sinonjs/fake-timers": {
+ "version": "9.1.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz",
+ "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==",
"dev": true,
- "requires": {
+ "dependencies": {
"@sinonjs/commons": "^1.7.0"
}
},
- "@szmarczak/http-timer": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
- "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
- "dev": true,
- "requires": {
- "defer-to-connect": "^1.0.1"
- }
- },
- "@types/babel__core": {
- "version": "7.1.7",
- "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.7.tgz",
- "integrity": "sha512-RL62NqSFPCDK2FM1pSDH0scHpJvsXtZNiYlMB73DgPBaG1E38ZYVL+ei5EkWRbr+KC4YNiAUNBnRj+bgwpgjMw==",
+ "node_modules/@types/babel__core": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
"dev": true,
- "requires": {
- "@babel/parser": "^7.1.0",
- "@babel/types": "^7.0.0",
+ "dependencies": {
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
"@types/babel__generator": "*",
"@types/babel__template": "*",
"@types/babel__traverse": "*"
}
},
- "@types/babel__generator": {
- "version": "7.6.1",
- "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz",
- "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==",
+ "node_modules/@types/babel__generator": {
+ "version": "7.6.8",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz",
+ "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==",
"dev": true,
- "requires": {
+ "dependencies": {
"@babel/types": "^7.0.0"
}
},
- "@types/babel__template": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz",
- "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==",
+ "node_modules/@types/babel__template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
"dev": true,
- "requires": {
+ "dependencies": {
"@babel/parser": "^7.1.0",
"@babel/types": "^7.0.0"
}
},
- "@types/babel__traverse": {
- "version": "7.0.11",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.11.tgz",
- "integrity": "sha512-ddHK5icION5U6q11+tV2f9Mo6CZVuT8GJKld2q9LqHSZbvLbH34Kcu2yFGckZut453+eQU6btIA3RihmnRgI+Q==",
+ "node_modules/@types/babel__traverse": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz",
+ "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==",
"dev": true,
- "requires": {
- "@babel/types": "^7.3.0"
+ "dependencies": {
+ "@babel/types": "^7.20.7"
}
},
- "@types/color-name": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
- "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
- "dev": true
- },
- "@types/graceful-fs": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz",
- "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==",
+ "node_modules/@types/graceful-fs": {
+ "version": "4.1.9",
+ "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
+ "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==",
"dev": true,
- "requires": {
+ "dependencies": {
"@types/node": "*"
}
},
- "@types/istanbul-lib-coverage": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.2.tgz",
- "integrity": "sha512-rsZg7eL+Xcxsxk2XlBt9KcG8nOp9iYdKCOikY9x2RFJCyOdNj4MKPQty0e8oZr29vVAzKXr1BmR+kZauti3o1w==",
+ "node_modules/@types/istanbul-lib-coverage": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
+ "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
"dev": true
},
- "@types/istanbul-lib-report": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
- "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==",
+ "node_modules/@types/istanbul-lib-report": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
+ "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
"dev": true,
- "requires": {
+ "dependencies": {
"@types/istanbul-lib-coverage": "*"
}
},
- "@types/istanbul-reports": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz",
- "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==",
+ "node_modules/@types/istanbul-reports": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
+ "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
"dev": true,
- "requires": {
- "@types/istanbul-lib-coverage": "*",
+ "dependencies": {
"@types/istanbul-lib-report": "*"
}
},
- "@types/node": {
- "version": "14.0.6",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.6.tgz",
- "integrity": "sha512-FbNmu4F67d3oZMWBV6Y4MaPER+0EpE9eIYf2yaHhCWovc1dlXCZkqGX4NLHfVVr6umt20TNBdRzrNJIzIKfdbw=="
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="
},
- "@types/normalize-package-data": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
- "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
- "dev": true
+ "node_modules/@types/node": {
+ "version": "20.11.25",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.25.tgz",
+ "integrity": "sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==",
+ "dependencies": {
+ "undici-types": "~5.26.4"
+ }
},
- "@types/prettier": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz",
- "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==",
+ "node_modules/@types/prettier": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz",
+ "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==",
"dev": true
},
- "@types/stack-utils": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
- "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==",
+ "node_modules/@types/stack-utils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
+ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
"dev": true
},
- "@types/yargs": {
- "version": "15.0.5",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz",
- "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==",
+ "node_modules/@types/yargs": {
+ "version": "17.0.32",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz",
+ "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==",
"dev": true,
- "requires": {
+ "dependencies": {
"@types/yargs-parser": "*"
}
},
- "@types/yargs-parser": {
- "version": "15.0.0",
- "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz",
- "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==",
- "dev": true
- },
- "abab": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz",
- "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==",
+ "node_modules/@types/yargs-parser": {
+ "version": "21.0.3",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
+ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
"dev": true
},
- "abbrev": {
+ "node_modules/abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
},
- "acorn": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz",
- "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==",
- "dev": true
- },
- "acorn-globals": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz",
- "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==",
- "dev": true,
- "requires": {
- "acorn": "^7.1.1",
- "acorn-walk": "^7.1.1"
- }
- },
- "acorn-walk": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz",
- "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==",
- "dev": true
- },
- "agent-base": {
+ "node_modules/agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
- "requires": {
+ "dependencies": {
"debug": "4"
},
- "dependencies": {
- "debug": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
- "requires": {
- "ms": "2.1.2"
- }
- }
+ "engines": {
+ "node": ">= 6.0.0"
}
},
- "ajv": {
- "version": "6.10.2",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
- "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
- "requires": {
- "fast-deep-equal": "^2.0.1",
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
- }
- },
- "ansi-align": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz",
- "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==",
- "dev": true,
- "requires": {
- "string-width": "^3.0.0"
},
- "dependencies": {
- "ansi-regex": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
- "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
- "dev": true
- },
- "emoji-regex": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
- "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
- "dev": true
- },
- "string-width": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
- "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
- "dev": true,
- "requires": {
- "emoji-regex": "^7.0.1",
- "is-fullwidth-code-point": "^2.0.0",
- "strip-ansi": "^5.1.0"
- }
- },
- "strip-ansi": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
- "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
- "dev": true,
- "requires": {
- "ansi-regex": "^4.1.0"
- }
- }
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
}
},
- "ansi-escapes": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
- "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
+ "node_modules/ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
"dev": true,
- "requires": {
- "type-fest": "^0.11.0"
- },
"dependencies": {
- "type-fest": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
- "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==",
- "dev": true
- }
+ "type-fest": "^0.21.3"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "engines": {
+ "node": ">=8"
+ }
},
- "ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "requires": {
- "color-convert": "^1.9.0"
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "any-promise": {
+ "node_modules/any-promise": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
- "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="
},
- "anymatch": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
- "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"dev": true,
- "requires": {
- "micromatch": "^3.1.4",
- "normalize-path": "^2.1.1"
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
}
},
- "aproba": {
+ "node_modules/aproba": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
"integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
},
- "are-we-there-yet": {
+ "node_modules/are-we-there-yet": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
"integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
- "requires": {
+ "dependencies": {
"delegates": "^1.0.0",
"readable-stream": "^3.6.0"
},
- "dependencies": {
- "readable-stream": {
- "version": "3.6.2",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
- "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
- "requires": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- }
- }
- }
- },
- "argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "requires": {
- "sprintf-js": "~1.0.2"
+ "engines": {
+ "node": ">=10"
}
},
- "arr-diff": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
- "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
- "dev": true
- },
- "arr-flatten": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
- "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
- "dev": true
- },
- "arr-union": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
- "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
- "dev": true
- },
- "array-unique": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
- "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
- "dev": true
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
- "asn1": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
- "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
- "requires": {
+ "node_modules/asn1": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
+ "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
+ "dependencies": {
"safer-buffer": "~2.1.0"
}
},
- "assert-plus": {
+ "node_modules/assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
- "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
- },
- "assign-symbols": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
- "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
- "dev": true
+ "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
+ "engines": {
+ "node": ">=0.8"
+ }
},
- "asynckit": {
+ "node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
- },
- "atob": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
- "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
- "dev": true
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
- "aws-sign2": {
+ "node_modules/aws-sign2": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
- "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
- },
- "aws4": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
- "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
- },
- "axios": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz",
- "integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==",
- "requires": {
- "follow-redirects": "^1.15.0",
+ "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/aws4": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz",
+ "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg=="
+ },
+ "node_modules/axios": {
+ "version": "1.6.7",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz",
+ "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==",
+ "dependencies": {
+ "follow-redirects": "^1.15.4",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
- },
- "dependencies": {
- "form-data": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
- "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
- "requires": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "mime-types": "^2.1.12"
- }
- }
}
},
- "babel-jest": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.0.1.tgz",
- "integrity": "sha512-Z4GGmSNQ8pX3WS1O+6v3fo41YItJJZsVxG5gIQ+HuB/iuAQBJxMTHTwz292vuYws1LnHfwSRgoqI+nxdy/pcvw==",
+ "node_modules/babel-jest": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz",
+ "integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==",
"dev": true,
- "requires": {
- "@jest/transform": "^26.0.1",
- "@jest/types": "^26.0.1",
- "@types/babel__core": "^7.1.7",
- "babel-plugin-istanbul": "^6.0.0",
- "babel-preset-jest": "^26.0.0",
+ "dependencies": {
+ "@jest/transform": "^28.1.3",
+ "@types/babel__core": "^7.1.14",
+ "babel-plugin-istanbul": "^6.1.1",
+ "babel-preset-jest": "^28.1.3",
"chalk": "^4.0.0",
- "graceful-fs": "^4.2.4",
+ "graceful-fs": "^4.2.9",
"slash": "^3.0.0"
},
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "graceful-fs": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
- "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.8.0"
}
},
- "babel-plugin-istanbul": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz",
- "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==",
+ "node_modules/babel-plugin-istanbul": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
+ "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==",
"dev": true,
- "requires": {
+ "dependencies": {
"@babel/helper-plugin-utils": "^7.0.0",
"@istanbuljs/load-nyc-config": "^1.0.0",
"@istanbuljs/schema": "^0.1.2",
- "istanbul-lib-instrument": "^4.0.0",
+ "istanbul-lib-instrument": "^5.0.4",
"test-exclude": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "babel-plugin-jest-hoist": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.0.0.tgz",
- "integrity": "sha512-+AuoehOrjt9irZL7DOt2+4ZaTM6dlu1s5TTS46JBa0/qem4dy7VNW3tMb96qeEqcIh20LD73TVNtmVEeymTG7w==",
+ "node_modules/babel-plugin-jest-hoist": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz",
+ "integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==",
"dev": true,
- "requires": {
+ "dependencies": {
"@babel/template": "^7.3.3",
"@babel/types": "^7.3.3",
+ "@types/babel__core": "^7.1.14",
"@types/babel__traverse": "^7.0.6"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "babel-preset-current-node-syntax": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.2.tgz",
- "integrity": "sha512-u/8cS+dEiK1SFILbOC8/rUI3ml9lboKuuMvZ/4aQnQmhecQAgPw5ew066C1ObnEAUmlx7dv/s2z52psWEtLNiw==",
+ "node_modules/babel-preset-current-node-syntax": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz",
+ "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==",
"dev": true,
- "requires": {
+ "dependencies": {
"@babel/plugin-syntax-async-generators": "^7.8.4",
"@babel/plugin-syntax-bigint": "^7.8.3",
"@babel/plugin-syntax-class-properties": "^7.8.3",
+ "@babel/plugin-syntax-import-meta": "^7.8.3",
"@babel/plugin-syntax-json-strings": "^7.8.3",
"@babel/plugin-syntax-logical-assignment-operators": "^7.8.3",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
"@babel/plugin-syntax-numeric-separator": "^7.8.3",
"@babel/plugin-syntax-object-rest-spread": "^7.8.3",
"@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3"
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-syntax-top-level-await": "^7.8.3"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
}
},
- "babel-preset-jest": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.0.0.tgz",
- "integrity": "sha512-9ce+DatAa31DpR4Uir8g4Ahxs5K4W4L8refzt+qHWQANb6LhGcAEfIFgLUwk67oya2cCUd6t4eUMtO/z64ocNw==",
+ "node_modules/babel-preset-jest": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz",
+ "integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==",
"dev": true,
- "requires": {
- "babel-plugin-jest-hoist": "^26.0.0",
- "babel-preset-current-node-syntax": "^0.1.2"
+ "dependencies": {
+ "babel-plugin-jest-hoist": "^28.1.3",
+ "babel-preset-current-node-syntax": "^1.0.0"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
}
},
- "balanced-match": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
- },
- "base": {
- "version": "0.11.2",
- "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
- "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
- "dev": true,
- "requires": {
- "cache-base": "^1.0.1",
- "class-utils": "^0.3.5",
- "component-emitter": "^1.2.1",
- "define-property": "^1.0.0",
- "isobject": "^3.0.1",
- "mixin-deep": "^1.2.0",
- "pascalcase": "^0.1.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- }
- }
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
- "bcrypt": {
+ "node_modules/bcrypt": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz",
"integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==",
- "requires": {
+ "hasInstallScript": true,
+ "dependencies": {
"@mapbox/node-pre-gyp": "^1.0.11",
"node-addon-api": "^5.0.0"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
}
},
- "bcrypt-pbkdf": {
+ "node_modules/bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
- "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
- "requires": {
+ "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
+ "dependencies": {
"tweetnacl": "^0.14.3"
}
},
- "binary-extensions": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz",
- "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==",
- "dev": true
- },
- "bl": {
+ "node_modules/binary-extensions": {
"version": "2.2.0",
- "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.0.tgz",
- "integrity": "sha512-wbgvOpqopSr7uq6fJrLH8EsvYMJf9gzfo2jCsL2eTy75qXPukA4pCgHamOQkZtY5vmfVtjB+P3LNlMHW5CEZXA==",
- "requires": {
- "readable-stream": "^2.3.5",
- "safe-buffer": "^5.1.1"
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
}
},
- "blipp": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/blipp/-/blipp-4.0.1.tgz",
- "integrity": "sha512-nmtErzngVgJF6HlpnEymOil23m5U82oTYhbU8m619kQzj8yJ2q1ZFbL45i+dBcO92XTocyyj3QtC3GMxRujv8w==",
- "requires": {
- "@hapi/hoek": "8.x.x",
- "@hapi/joi": "15.x.x",
- "chalk": "2.x.x",
- "easy-table": "1.x.x"
- },
- "dependencies": {
- "@hapi/joi": {
- "version": "15.1.1",
- "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz",
- "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==",
- "requires": {
- "@hapi/address": "2.x.x",
- "@hapi/bourne": "1.x.x",
- "@hapi/hoek": "8.x.x",
- "@hapi/topo": "3.x.x"
- }
- }
+ "node_modules/blipp": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/blipp/-/blipp-4.0.2.tgz",
+ "integrity": "sha512-QA5amT0IFJgCFgJeWw2udD2zZLui60NgqXTyvbSq+qpVbS6jfqELTRlC8PWW0yD4+chdZ2a+svnN6WE9zqfK5Q==",
+ "dependencies": {
+ "@hapi/hoek": "9.x.x",
+ "chalk": "4.x.x",
+ "easy-table": "1.x.x",
+ "joi": "17.x.x"
}
},
- "bluebird": {
+ "node_modules/blipp/node_modules/@hapi/hoek": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
+ "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
+ },
+ "node_modules/bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
},
- "boxen": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz",
- "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==",
- "dev": true,
- "requires": {
- "ansi-align": "^3.0.0",
- "camelcase": "^5.3.1",
- "chalk": "^3.0.0",
- "cli-boxes": "^2.2.0",
- "string-width": "^4.1.0",
- "term-size": "^2.1.0",
- "type-fest": "^0.8.1",
- "widest-line": "^3.1.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
- "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "brace-expansion": {
+ "node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "requires": {
+ "dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
- "braces": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
- "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
- "dev": true,
- "requires": {
- "arr-flatten": "^1.1.0",
- "array-unique": "^0.3.2",
- "extend-shallow": "^2.0.1",
- "fill-range": "^4.0.0",
- "isobject": "^3.0.1",
- "repeat-element": "^1.1.2",
- "snapdragon": "^0.8.1",
- "snapdragon-node": "^2.0.1",
- "split-string": "^3.0.2",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "browser-process-hrtime": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
- "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==",
- "dev": true
+ "node_modules/browserslist": {
+ "version": "4.23.0",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
+ "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001587",
+ "electron-to-chromium": "^1.4.668",
+ "node-releases": "^2.0.14",
+ "update-browserslist-db": "^1.0.13"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
},
- "bser": {
+ "node_modules/bser": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
"integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
"dev": true,
- "requires": {
+ "dependencies": {
"node-int64": "^0.4.0"
}
},
- "bson": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.4.tgz",
- "integrity": "sha512-S/yKGU1syOMzO86+dGpg2qGoDL0zvzcb262G+gqEy6TgP6rt6z6qxSFX/8X6vLC91P7G7C3nLs0+bvDzmvBA3Q=="
- },
- "buffer-equal-constant-time": {
+ "node_modules/buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
},
- "buffer-from": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
- "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"dev": true
},
- "cache-base": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
- "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
- "dev": true,
- "requires": {
- "collection-visit": "^1.0.0",
- "component-emitter": "^1.2.1",
- "get-value": "^2.0.6",
- "has-value": "^1.0.0",
- "isobject": "^3.0.1",
- "set-value": "^2.0.0",
- "to-object-path": "^0.3.0",
- "union-value": "^1.0.0",
- "unset-value": "^1.0.0"
- }
- },
- "cacheable-request": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
- "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
- "dev": true,
- "requires": {
- "clone-response": "^1.0.2",
- "get-stream": "^5.1.0",
- "http-cache-semantics": "^4.0.0",
- "keyv": "^3.0.0",
- "lowercase-keys": "^2.0.0",
- "normalize-url": "^4.1.0",
- "responselike": "^1.0.2"
- },
- "dependencies": {
- "get-stream": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
- "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==",
- "dev": true,
- "requires": {
- "pump": "^3.0.0"
- }
- },
- "lowercase-keys": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
- "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
- "dev": true
- },
- "pump": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
- "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
- "dev": true,
- "requires": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- }
- }
- },
- "call-me-maybe": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz",
- "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms="
+ "node_modules/call-me-maybe": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz",
+ "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ=="
},
- "callsites": {
+ "node_modules/callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
- "dev": true
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
},
- "camelcase": {
+ "node_modules/camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
- "dev": true
- },
- "capture-exit": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",
- "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==",
"dev": true,
- "requires": {
- "rsvp": "^4.8.4"
+ "engines": {
+ "node": ">=6"
}
},
- "caseless": {
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001596",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001596.tgz",
+ "integrity": "sha512-zpkZ+kEr6We7w63ORkoJ2pOfBwBkY/bJrG/UZ90qNb45Isblu8wzDgevEOrRL1r9dWayHjYiiyCMEXPn4DweGQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ]
+ },
+ "node_modules/caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
- "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+ "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
},
- "chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "requires": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
}
},
- "char-regex": {
+ "node_modules/char-regex": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
"integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
- "dev": true
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
},
- "chokidar": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz",
- "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==",
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
"dev": true,
- "requires": {
- "anymatch": "~3.1.1",
+ "dependencies": {
+ "anymatch": "~3.1.2",
"braces": "~3.0.2",
- "fsevents": "~2.1.2",
- "glob-parent": "~5.1.0",
+ "glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
- "readdirp": "~3.4.0"
- },
- "dependencies": {
- "anymatch": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
- "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
- "dev": true,
- "requires": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- }
- },
- "braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
- "dev": true,
- "requires": {
- "fill-range": "^7.0.1"
- }
- },
- "fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
- "dev": true,
- "requires": {
- "to-regex-range": "^5.0.1"
- }
- },
- "is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true
- },
- "normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true
- },
- "to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "requires": {
- "is-number": "^7.0.0"
- }
- }
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
}
},
- "chownr": {
+ "node_modules/chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
- "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="
- },
- "ci-info": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
- "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
- "dev": true
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "engines": {
+ "node": ">=10"
+ }
},
- "class-utils": {
- "version": "0.3.6",
- "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
- "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
- "dev": true,
- "requires": {
- "arr-union": "^3.1.0",
- "define-property": "^0.2.5",
- "isobject": "^3.0.0",
- "static-extend": "^0.1.1"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
+ "node_modules/ci-info": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
+ "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
}
+ ],
+ "engines": {
+ "node": ">=8"
}
},
- "cli-boxes": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz",
- "integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==",
+ "node_modules/cjs-module-lexer": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz",
+ "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==",
"dev": true
},
- "cliui": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
- "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"dev": true,
- "requires": {
+ "dependencies": {
"string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
- "wrap-ansi": "^6.2.0"
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
}
},
- "clone": {
+ "node_modules/clone": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
- "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
- "optional": true
- },
- "clone-response": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
- "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
- "dev": true,
- "requires": {
- "mimic-response": "^1.0.0"
+ "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
+ "optional": true,
+ "engines": {
+ "node": ">=0.8"
}
},
- "cls-bluebird": {
+ "node_modules/cls-bluebird": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/cls-bluebird/-/cls-bluebird-2.1.0.tgz",
- "integrity": "sha1-N+8eCAqP+1XC9BZPU28ZGeeWiu4=",
- "requires": {
+ "integrity": "sha512-XVb0RPmHQyy35Tz9z34gvtUcBKUK8A/1xkGCyeFc9B0C7Zr5SysgFaswRVdwI5NEMcO+3JKlIDGIOgERSn9NdA==",
+ "dependencies": {
"is-bluebird": "^1.0.2",
"shimmer": "^1.1.0"
}
},
- "co": {
+ "node_modules/co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
- "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
- "dev": true
- },
- "collect-v8-coverage": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz",
- "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==",
- "dev": true
- },
- "collection-visit": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
- "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
"dev": true,
- "requires": {
- "map-visit": "^1.0.0",
- "object-visit": "^1.0.0"
+ "engines": {
+ "iojs": ">= 1.0.0",
+ "node": ">= 0.12.0"
}
},
- "color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "requires": {
- "color-name": "1.1.3"
+ "node_modules/collect-v8-coverage": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz",
+ "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==",
+ "dev": true
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
}
},
- "color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
- "color-support": {
+ "node_modules/color-support": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
- "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg=="
+ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
+ "bin": {
+ "color-support": "bin.js"
+ }
},
- "combined-stream": {
+ "node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "requires": {
+ "dependencies": {
"delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
}
},
- "commander": {
- "version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "optional": true
- },
- "component-emitter": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
- "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
- "dev": true
+ "node_modules/commander": {
+ "version": "9.5.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz",
+ "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
+ "optional": true,
+ "engines": {
+ "node": "^12.20.0 || >=14"
+ }
},
- "concat-map": {
+ "node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
- },
- "configstore": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz",
- "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==",
- "dev": true,
- "requires": {
- "dot-prop": "^5.2.0",
- "graceful-fs": "^4.1.2",
- "make-dir": "^3.0.0",
- "unique-string": "^2.0.0",
- "write-file-atomic": "^3.0.0",
- "xdg-basedir": "^4.0.0"
- }
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
},
- "console-control-strings": {
+ "node_modules/console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
},
- "convert-source-map": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
- "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.1.1"
- }
- },
- "copy-descriptor": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
- "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+ "node_modules/convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
"dev": true
},
- "core-js": {
- "version": "2.6.11",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz",
- "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg=="
- },
- "core-util-is": {
+ "node_modules/core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
- },
- "cross-spawn": {
- "version": "6.0.5",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
- "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
- "dev": true,
- "requires": {
- "nice-try": "^1.0.4",
- "path-key": "^2.0.1",
- "semver": "^5.5.0",
- "shebang-command": "^1.2.0",
- "which": "^1.2.9"
- }
- },
- "crypto-random-string": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
- "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
- "dev": true
- },
- "cssom": {
- "version": "0.4.4",
- "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz",
- "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==",
- "dev": true
+ "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="
},
- "cssstyle": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz",
- "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"dev": true,
- "requires": {
- "cssom": "~0.3.6"
- },
"dependencies": {
- "cssom": {
- "version": "0.3.8",
- "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
- "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
- "dev": true
- }
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
}
},
- "dashdash": {
+ "node_modules/dashdash": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
- "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
- "requires": {
+ "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
+ "dependencies": {
"assert-plus": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10"
}
},
- "data-urls": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz",
- "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==",
- "dev": true,
- "requires": {
- "abab": "^2.0.3",
- "whatwg-mimetype": "^2.3.0",
- "whatwg-url": "^8.0.0"
- }
- },
- "debug": {
- "version": "3.2.6",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
- "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
- "requires": {
- "ms": "^2.1.1"
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
}
},
- "decamelize": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
- "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
- "dev": true
- },
- "decimal.js": {
- "version": "10.2.0",
- "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz",
- "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw==",
- "dev": true
- },
- "decode-uri-component": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
- "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+ "node_modules/dedent": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
+ "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==",
"dev": true
},
- "decompress-response": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
- "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+ "node_modules/deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"dev": true,
- "requires": {
- "mimic-response": "^1.0.0"
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "deep-extend": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
- "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
- "dev": true
- },
- "deep-is": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
- "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
- "dev": true
- },
- "deepmerge": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
- "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
- "dev": true
- },
- "defaults": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
- "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
+ "node_modules/defaults": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
+ "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
"optional": true,
- "requires": {
+ "dependencies": {
"clone": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "defer-to-connect": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
- "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
- "dev": true
- },
- "define-property": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
- "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.2",
- "isobject": "^3.0.1"
- },
- "dependencies": {
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- }
- }
- },
- "delayed-stream": {
+ "node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "engines": {
+ "node": ">=0.4.0"
+ }
},
- "delegates": {
+ "node_modules/delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
},
- "denque": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz",
- "integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ=="
+ "node_modules/denque": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
+ "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==",
+ "engines": {
+ "node": ">=0.10"
+ }
},
- "detect-libc": {
+ "node_modules/detect-libc": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz",
- "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw=="
+ "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==",
+ "engines": {
+ "node": ">=8"
+ }
},
- "detect-newline": {
+ "node_modules/detect-newline": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
"integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
- "dev": true
- },
- "diff-sequences": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz",
- "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==",
- "dev": true
- },
- "domexception": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz",
- "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==",
"dev": true,
- "requires": {
- "webidl-conversions": "^5.0.0"
- },
- "dependencies": {
- "webidl-conversions": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz",
- "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==",
- "dev": true
- }
+ "engines": {
+ "node": ">=8"
}
},
- "dot-prop": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz",
- "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==",
+ "node_modules/diff-sequences": {
+ "version": "28.1.1",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz",
+ "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==",
"dev": true,
- "requires": {
- "is-obj": "^2.0.0"
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "dotenv": {
+ "node_modules/dotenv": {
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz",
- "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g=="
- },
- "dottie": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.2.tgz",
- "integrity": "sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg=="
- },
- "duplexer3": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
- "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
- "dev": true
- },
- "duplexify": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
- "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
- "requires": {
- "end-of-stream": "^1.0.0",
- "inherits": "^2.0.1",
- "readable-stream": "^2.0.0",
- "stream-shift": "^1.0.0"
+ "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==",
+ "engines": {
+ "node": ">=10"
}
},
- "easy-table": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.1.1.tgz",
- "integrity": "sha512-C9Lvm0WFcn2RgxbMnTbXZenMIWcBtkzMr+dWqq/JsVoGFSVUVlPqeOa5LP5kM0I3zoOazFpckOEb2/0LDFfToQ==",
- "requires": {
- "ansi-regex": "^3.0.0",
- "wcwidth": ">=1.0.1"
+ "node_modules/dottie": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.6.tgz",
+ "integrity": "sha512-iGCHkfUc5kFekGiqhe8B/mdaurD+lakO9txNnTvKtA6PISrw86LgqHvRzWYPyoE2Ph5aMIrCw9/uko6XHTKCwA=="
+ },
+ "node_modules/easy-table": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.2.0.tgz",
+ "integrity": "sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww==",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "optionalDependencies": {
+ "wcwidth": "^1.0.1"
}
},
- "ecc-jsbn": {
+ "node_modules/ecc-jsbn": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
- "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
- "requires": {
+ "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
+ "dependencies": {
"jsbn": "~0.1.0",
"safer-buffer": "^2.1.0"
}
},
- "ecdsa-sig-formatter": {
+ "node_modules/ecdsa-sig-formatter": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
- "requires": {
+ "dependencies": {
"safe-buffer": "^5.0.1"
}
},
- "emoji-regex": {
+ "node_modules/electron-to-chromium": {
+ "version": "1.4.695",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.695.tgz",
+ "integrity": "sha512-eMijZmeqPtm774pCZIOrfUHMs/7ls++W1sLhxwqgu8KQ8E2WmMtzwyqOMt0XXUJ3HTIPfuwlfwF+I5cwnfItBA==",
+ "dev": true
+ },
+ "node_modules/emittery": {
+ "version": "0.10.2",
+ "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz",
+ "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/emittery?sponsor=1"
+ }
+ },
+ "node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
- "end-of-stream": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
- "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
- "requires": {
- "once": "^1.4.0"
- }
- },
- "error-ex": {
+ "node_modules/error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
"dev": true,
- "requires": {
+ "dependencies": {
"is-arrayish": "^0.2.1"
}
},
- "escape-goat": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz",
- "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==",
- "dev": true
- },
- "escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+ "node_modules/escalade": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
+ "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
},
- "escodegen": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.1.tgz",
- "integrity": "sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==",
+ "node_modules/escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
"dev": true,
- "requires": {
- "esprima": "^4.0.1",
- "estraverse": "^4.2.0",
- "esutils": "^2.0.2",
- "optionator": "^0.8.1",
- "source-map": "~0.6.1"
+ "engines": {
+ "node": ">=8"
}
},
- "esprima": {
+ "node_modules/esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
- },
- "estraverse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
- "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
- "dev": true
- },
- "esutils": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
- "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
- "dev": true
- },
- "exec-sh": {
- "version": "0.3.4",
- "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz",
- "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==",
- "dev": true
- },
- "execa": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
- "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
- "dev": true,
- "requires": {
- "cross-spawn": "^6.0.0",
- "get-stream": "^4.0.0",
- "is-stream": "^1.1.0",
- "npm-run-path": "^2.0.0",
- "p-finally": "^1.0.0",
- "signal-exit": "^3.0.0",
- "strip-eof": "^1.0.0"
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
}
},
- "exit": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
- "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
- "dev": true
- },
- "expand-brackets": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
- "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "node_modules/execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
"dev": true,
- "requires": {
- "debug": "^2.3.3",
- "define-property": "^0.2.5",
- "extend-shallow": "^2.0.1",
- "posix-character-classes": "^0.1.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
"dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
- "dev": true
- }
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
- "expect": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz",
- "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==",
+ "node_modules/exit": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
"dev": true,
- "requires": {
- "@jest/types": "^26.0.1",
- "ansi-styles": "^4.0.0",
- "jest-get-type": "^26.0.0",
- "jest-matcher-utils": "^26.0.1",
- "jest-message-util": "^26.0.1",
- "jest-regex-util": "^26.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- }
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/expect": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz",
+ "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==",
+ "dev": true,
+ "dependencies": {
+ "@jest/expect-utils": "^28.1.3",
+ "jest-get-type": "^28.0.2",
+ "jest-matcher-utils": "^28.1.3",
+ "jest-message-util": "^28.1.3",
+ "jest-util": "^28.1.3"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "extend": {
+ "node_modules/extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
},
- "extend-shallow": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
- "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
- "dev": true,
- "requires": {
- "assign-symbols": "^1.0.0",
- "is-extendable": "^1.0.1"
- },
- "dependencies": {
- "is-extendable": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
- "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
- "dev": true,
- "requires": {
- "is-plain-object": "^2.0.4"
- }
- }
- }
- },
- "extglob": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
- "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
- "dev": true,
- "requires": {
- "array-unique": "^0.3.2",
- "define-property": "^1.0.0",
- "expand-brackets": "^2.1.4",
- "extend-shallow": "^2.0.1",
- "fragment-cache": "^0.2.1",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- }
- }
- },
- "extsprintf": {
+ "node_modules/extsprintf": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
- "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
- },
- "fast-deep-equal": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
- "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk="
- },
- "fast-json-stable-stringify": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
- "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
+ "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==",
+ "engines": [
+ "node >=0.6.0"
+ ]
},
- "fast-levenshtein": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
- "dev": true
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
- "fast-safe-stringify": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz",
- "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA=="
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
},
- "fb-watchman": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz",
- "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==",
+ "node_modules/fb-watchman": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
+ "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
"dev": true,
- "requires": {
+ "dependencies": {
"bser": "2.1.1"
}
},
- "fill-range": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
- "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
- "dev": true,
- "requires": {
- "extend-shallow": "^2.0.1",
- "is-number": "^3.0.0",
- "repeat-string": "^1.6.1",
- "to-regex-range": "^2.1.0"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "find-up": {
+ "node_modules/find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
- "requires": {
+ "dependencies": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "follow-redirects": {
- "version": "1.15.3",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
- "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q=="
- },
- "for-in": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
- "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
- "dev": true
+ "node_modules/follow-redirects": {
+ "version": "1.15.5",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz",
+ "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
},
- "forever-agent": {
+ "node_modules/forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
- "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
+ "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==",
+ "engines": {
+ "node": "*"
+ }
},
- "form-data": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
- "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
- "requires": {
+ "node_modules/form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "dependencies": {
"asynckit": "^0.4.0",
- "combined-stream": "^1.0.6",
+ "combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
}
},
- "format-util": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/format-util/-/format-util-1.0.5.tgz",
- "integrity": "sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg=="
- },
- "fragment-cache": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
- "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
- "dev": true,
- "requires": {
- "map-cache": "^0.2.2"
- }
- },
- "fs-minipass": {
+ "node_modules/fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
- "requires": {
+ "dependencies": {
"minipass": "^3.0.0"
},
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/fs-minipass/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"dependencies": {
- "minipass": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
- "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
- "requires": {
- "yallist": "^4.0.0"
- }
- }
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "fs.realpath": {
+ "node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
- "fsevents": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
- "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
- "optional": true
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
},
- "gauge": {
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gauge": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
"integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
- "requires": {
+ "dependencies": {
"aproba": "^1.0.3 || ^2.0.0",
"color-support": "^1.1.2",
"console-control-strings": "^1.0.0",
@@ -3805,2439 +2810,1238 @@
"strip-ansi": "^6.0.1",
"wide-align": "^1.1.2"
},
- "dependencies": {
- "ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
- },
- "is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
- },
- "string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "requires": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- }
- },
- "strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "requires": {
- "ansi-regex": "^5.0.1"
- }
- }
+ "engines": {
+ "node": ">=10"
}
},
- "generate-function": {
+ "node_modules/generate-function": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
"integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==",
- "requires": {
+ "dependencies": {
"is-property": "^1.0.2"
}
},
- "gensync": {
- "version": "1.0.0-beta.1",
- "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
- "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==",
- "dev": true
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
},
- "get-caller-file": {
+ "node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
- "dev": true
+ "dev": true,
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
},
- "get-package-type": {
+ "node_modules/get-package-type": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
"integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
- "dev": true
- },
- "get-stream": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
- "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
- "dev": true,
- "requires": {
- "pump": "^3.0.0"
- },
- "dependencies": {
- "pump": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
- "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
- "dev": true,
- "requires": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- }
+ "dev": true,
+ "engines": {
+ "node": ">=8.0.0"
}
},
- "get-value": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
- "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
- "dev": true
+ "node_modules/get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
},
- "getpass": {
+ "node_modules/getpass": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
- "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
- "requires": {
+ "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
+ "dependencies": {
"assert-plus": "^1.0.0"
}
},
- "glob": {
- "version": "7.1.5",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz",
- "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==",
- "requires": {
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
- "minimatch": "^3.0.4",
+ "minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "glob-parent": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
- "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
- "requires": {
+ "dependencies": {
"is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
}
},
- "global-dirs": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz",
- "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==",
- "dev": true,
- "requires": {
- "ini": "^1.3.5"
- }
- },
- "globals": {
+ "node_modules/globals": {
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
- "dev": true
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
},
- "got": {
- "version": "9.6.0",
- "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
- "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
- "dev": true,
- "requires": {
- "@sindresorhus/is": "^0.14.0",
- "@szmarczak/http-timer": "^1.1.2",
- "cacheable-request": "^6.0.0",
- "decompress-response": "^3.3.0",
- "duplexer3": "^0.1.4",
- "get-stream": "^4.1.0",
- "lowercase-keys": "^1.0.1",
- "mimic-response": "^1.0.1",
- "p-cancelable": "^1.0.0",
- "to-readable-stream": "^1.0.0",
- "url-parse-lax": "^3.0.0"
- }
- },
- "graceful-fs": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
- "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"dev": true
},
- "growly": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
- "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
- "dev": true,
- "optional": true
+ "node_modules/handlebars": {
+ "version": "4.7.8",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
+ "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==",
+ "dependencies": {
+ "minimist": "^1.2.5",
+ "neo-async": "^2.6.2",
+ "source-map": "^0.6.1",
+ "wordwrap": "^1.0.0"
+ },
+ "bin": {
+ "handlebars": "bin/handlebars"
+ },
+ "engines": {
+ "node": ">=0.4.7"
+ },
+ "optionalDependencies": {
+ "uglify-js": "^3.1.4"
+ }
},
- "hapi-swagger": {
- "version": "13.0.2",
- "resolved": "https://registry.npmjs.org/hapi-swagger/-/hapi-swagger-13.0.2.tgz",
- "integrity": "sha512-fPUSVPLh1tpCS1q1ECUhmxL3sZCo6MmrQArwZIoh7QrwN7Tmw2zprz5nGS96KjSQE/MDJOfq82pdEq6FHD7yIQ==",
- "requires": {
- "@hapi/boom": "^8.0.1",
- "@hapi/hoek": "^9.0.2",
- "handlebars": "^4.5.3",
- "http-status": "^1.0.1",
- "json-schema-ref-parser": "^6.1.0",
- "swagger-parser": "4.0.2",
- "swagger-ui-dist": "^3.22.1"
- },
- "dependencies": {
- "@hapi/boom": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-8.0.1.tgz",
- "integrity": "sha512-SnBM2GzEYEA6AGFKXBqNLWXR3uNBui0bkmklYXX1gYtevVhDTy2uakwkSauxvIWMtlANGRhzChYg95If3FWCwA==",
- "requires": {
- "@hapi/hoek": "8.x.x"
- },
- "dependencies": {
- "@hapi/hoek": {
- "version": "8.5.1",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz",
- "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow=="
- }
- }
- },
- "@hapi/hoek": {
- "version": "9.0.4",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.4.tgz",
- "integrity": "sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw=="
- },
- "handlebars": {
- "version": "4.7.6",
- "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz",
- "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==",
- "requires": {
- "minimist": "^1.2.5",
- "neo-async": "^2.6.0",
- "source-map": "^0.6.1",
- "uglify-js": "^3.1.4",
- "wordwrap": "^1.0.0"
- }
- },
- "minimist": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
- "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
- },
- "wordwrap": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
- "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
- }
+ "node_modules/hapi-cors": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/hapi-cors/-/hapi-cors-1.0.3.tgz",
+ "integrity": "sha512-45fkvy13d+Awp25OXuMj8imQSoD3x5SJ99D+P/WBEwruHArpoHdj+zMlrXOoixgo/O281/lls6rAZBnkBtNOpg==",
+ "deprecated": "This package is no longer being supported. Please migrate to the CORS functionality built into hapi.",
+ "dependencies": {
+ "joi": "^7.0.1"
+ }
+ },
+ "node_modules/hapi-cors/node_modules/joi": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/joi/-/joi-7.3.0.tgz",
+ "integrity": "sha512-7ysLFfGtSg5L1MWnIkJGvJLAsdZPLZK2+qAi+0D9QdsnlPVSk+dBZxEl1ezveJuhEcvZKLK+AZSkmnXeATcB0A==",
+ "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).",
+ "dependencies": {
+ "hoek": "3.x.x",
+ "isemail": "2.x.x",
+ "moment": "2.x.x",
+ "topo": "2.x.x"
+ },
+ "engines": {
+ "node": ">=4.0.0"
}
},
- "har-schema": {
+ "node_modules/hapi-swagger": {
+ "version": "17.2.1",
+ "resolved": "https://registry.npmjs.org/hapi-swagger/-/hapi-swagger-17.2.1.tgz",
+ "integrity": "sha512-IaF3OHfYjzDuyi5EQgS0j0xB7sbAAD4DaTwexdhPYqEBI/J7GWMXFbftGObCIOeMVDufjoSBZWeaarEkNn6/ww==",
+ "dependencies": {
+ "@apidevtools/json-schema-ref-parser": "^11.1.0",
+ "@hapi/boom": "^10.0.1",
+ "@hapi/hoek": "^11.0.2",
+ "handlebars": "^4.7.8",
+ "http-status": "^1.7.3",
+ "swagger-parser": "^10.0.3",
+ "swagger-ui-dist": "^5.9.1"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ },
+ "peerDependencies": {
+ "@hapi/hapi": ">=20.x.x",
+ "joi": "17.x"
+ }
+ },
+ "node_modules/har-schema": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
- "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
- },
- "har-validator": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
- "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
- "requires": {
- "ajv": "^6.5.5",
+ "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/har-validator": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
+ "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
+ "deprecated": "this library is no longer supported",
+ "dependencies": {
+ "ajv": "^6.12.3",
"har-schema": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
}
},
- "has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "engines": {
+ "node": ">=8"
+ }
},
- "has-unicode": {
+ "node_modules/has-unicode": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
},
- "has-value": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
- "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+ "node_modules/hasown": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz",
+ "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==",
"dev": true,
- "requires": {
- "get-value": "^2.0.6",
- "has-values": "^1.0.0",
- "isobject": "^3.0.0"
- }
- },
- "has-values": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
- "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
- "dev": true,
- "requires": {
- "is-number": "^3.0.0",
- "kind-of": "^4.0.0"
- },
- "dependencies": {
- "kind-of": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
- "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
}
},
- "has-yarn": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz",
- "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==",
- "dev": true
- },
- "hosted-git-info": {
- "version": "2.8.8",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
- "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
- "dev": true
- },
- "html-encoding-sniffer": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz",
- "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==",
- "dev": true,
- "requires": {
- "whatwg-encoding": "^1.0.5"
+ "node_modules/hoek": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-3.0.4.tgz",
+ "integrity": "sha512-VIMFzySNWnvVqBZIWJSHzun/dvtgYYxv0DypA8Mr9ue+kjXyf1mkq4/EOU/a33cIoW+fFyk9+t8W6ZSqucKYpA==",
+ "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).",
+ "engines": {
+ "node": ">=4.0.0"
}
},
- "html-escaper": {
+ "node_modules/html-escaper": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
"dev": true
},
- "http-cache-semantics": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
- "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
- "dev": true
- },
- "http-signature": {
+ "node_modules/http-signature": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
- "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
- "requires": {
+ "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==",
+ "dependencies": {
"assert-plus": "^1.0.0",
"jsprim": "^1.2.2",
"sshpk": "^1.7.0"
+ },
+ "engines": {
+ "node": ">=0.8",
+ "npm": ">=1.3.7"
}
},
- "http-status": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/http-status/-/http-status-1.4.2.tgz",
- "integrity": "sha512-mBnIohUwRw9NyXMEMMv8/GANnzEYUj0Y8d3uL01zDWFkxUjYyZ6rgCaAI2zZ1Wb34Oqtbx/nFZolPRDc8Xlm5A=="
+ "node_modules/http-status": {
+ "version": "1.7.4",
+ "resolved": "https://registry.npmjs.org/http-status/-/http-status-1.7.4.tgz",
+ "integrity": "sha512-c2qSwNtTlHVYAhMj9JpGdyo0No/+DiKXCJ9pHtZ2Yf3QmPnBIytKSRT7BuyIiQ7icXLynavGmxUqkOjSrAuMuA==",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
},
- "https-proxy-agent": {
+ "node_modules/https-proxy-agent": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
- "requires": {
+ "dependencies": {
"agent-base": "6",
"debug": "4"
},
- "dependencies": {
- "debug": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
- "requires": {
- "ms": "2.1.2"
- }
- }
+ "engines": {
+ "node": ">= 6"
}
},
- "human-signals": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
- "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
- "dev": true
+ "node_modules/human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.17.0"
+ }
},
- "husky": {
+ "node_modules/husky": {
"version": "8.0.3",
"resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz",
"integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==",
- "dev": true
- },
- "iconv-lite": {
- "version": "0.4.24",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
- "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"dev": true,
- "requires": {
- "safer-buffer": ">= 2.1.2 < 3"
+ "bin": {
+ "husky": "lib/bin.js"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/typicode"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "ignore-by-default": {
+ "node_modules/ignore-by-default": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
- "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=",
- "dev": true
- },
- "import-lazy": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
- "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=",
+ "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
"dev": true
},
- "import-local": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz",
- "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==",
+ "node_modules/import-local": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
+ "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
"dev": true,
- "requires": {
+ "dependencies": {
"pkg-dir": "^4.2.0",
"resolve-cwd": "^3.0.0"
+ },
+ "bin": {
+ "import-local-fixture": "fixtures/cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "imurmurhash": {
+ "node_modules/imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
- "dev": true
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.19"
+ }
},
- "inflection": {
+ "node_modules/inflection": {
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz",
- "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY="
+ "integrity": "sha512-lRy4DxuIFWXlJU7ed8UiTJOSTqStqYdEb4CEbtXfNbkdj3nH1L+reUWiE10VWcJS2yR7tge8Z74pJjtBjNwj0w==",
+ "engines": [
+ "node >= 0.4.0"
+ ]
},
- "inflight": {
+ "node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
- "requires": {
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dependencies": {
"once": "^1.3.0",
"wrappy": "1"
}
},
- "inherits": {
+ "node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
- "ini": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
- "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
- "dev": true
- },
- "ip-regex": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
- "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
- "dev": true
- },
- "is-accessor-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
- "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
+ "node_modules/install": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz",
+ "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==",
+ "engines": {
+ "node": ">= 0.10"
}
},
- "is-arrayish": {
+ "node_modules/is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
- "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
"dev": true
},
- "is-binary-path": {
+ "node_modules/is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dev": true,
- "requires": {
+ "dependencies": {
"binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "is-bluebird": {
+ "node_modules/is-bluebird": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-bluebird/-/is-bluebird-1.0.2.tgz",
- "integrity": "sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI="
+ "integrity": "sha512-PDRu1vVip5dGQg5tfn2qVCCyxbBYu5MhYUJwSfL/RoGBI97n1fxvilVazxzptZW0gcmsMH17H4EVZZI5E/RSeA==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
},
- "is-buffer": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
- "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
- "dev": true
+ "node_modules/is-core-module": {
+ "version": "2.13.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
+ "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
+ "dev": true,
+ "dependencies": {
+ "hasown": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
},
- "is-ci": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
- "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true,
- "requires": {
- "ci-info": "^2.0.0"
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "is-data-descriptor": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
- "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-generator-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
+ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
"dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
+ "engines": {
+ "node": ">=6"
}
},
- "is-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
- "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
- "requires": {
- "is-accessor-descriptor": "^0.1.6",
- "is-data-descriptor": "^0.1.4",
- "kind-of": "^5.0.0"
- },
"dependencies": {
- "kind-of": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
- "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
- "dev": true
- }
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "is-docker": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz",
- "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==",
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
- "optional": true
- },
- "is-extendable": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
- "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
- "dev": true
- },
- "is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
- "dev": true
- },
- "is-fullwidth-code-point": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
- "dev": true
- },
- "is-generator-fn": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
- "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
- "dev": true
- },
- "is-glob": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
- "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
- "dev": true,
- "requires": {
- "is-extglob": "^2.1.1"
- }
- },
- "is-installed-globally": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz",
- "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==",
- "dev": true,
- "requires": {
- "global-dirs": "^2.0.1",
- "is-path-inside": "^3.0.1"
- }
- },
- "is-npm": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz",
- "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==",
- "dev": true
- },
- "is-number": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
- "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
+ "engines": {
+ "node": ">=0.12.0"
}
},
- "is-obj": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
- "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
- "dev": true
- },
- "is-path-inside": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz",
- "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==",
- "dev": true
- },
- "is-plain-object": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
- "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
- "dev": true,
- "requires": {
- "isobject": "^3.0.1"
- }
- },
- "is-potential-custom-element-name": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz",
- "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=",
- "dev": true
- },
- "is-property": {
+ "node_modules/is-property": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
"integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g=="
},
- "is-stream": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
- "dev": true
+ "node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
},
- "is-typedarray": {
+ "node_modules/is-typedarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
- "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
- },
- "is-windows": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
- "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
- "dev": true
+ "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
},
- "is-wsl": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
- "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
- "dev": true,
- "optional": true,
- "requires": {
- "is-docker": "^2.0.0"
+ "node_modules/isemail": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/isemail/-/isemail-2.2.1.tgz",
+ "integrity": "sha512-LPjFxaTatluwGAJlGe4FtRdzg0a9KlXrahHoHAR4HwRNf90Ttwi6sOQ9zj+EoCPmk9yyK+WFUqkm0imUo8UJbw==",
+ "engines": {
+ "node": ">=4.0.0"
}
},
- "is-yarn-global": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz",
- "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==",
- "dev": true
- },
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "isexe": {
+ "node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
- "dev": true
- },
- "isobject": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
- "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true
},
- "isstream": {
+ "node_modules/isstream": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
- "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
+ "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="
},
- "istanbul-lib-coverage": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz",
- "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==",
- "dev": true
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+ "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
},
- "istanbul-lib-instrument": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz",
- "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==",
+ "node_modules/istanbul-lib-instrument": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
+ "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
"dev": true,
- "requires": {
- "@babel/core": "^7.7.5",
+ "dependencies": {
+ "@babel/core": "^7.12.3",
+ "@babel/parser": "^7.14.7",
"@istanbuljs/schema": "^0.1.2",
- "istanbul-lib-coverage": "^3.0.0",
+ "istanbul-lib-coverage": "^3.2.0",
"semver": "^6.3.0"
},
- "dependencies": {
- "semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
- "dev": true
- }
+ "engines": {
+ "node": ">=8"
}
},
- "istanbul-lib-report": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
- "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
+ "node_modules/istanbul-lib-instrument/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
"dev": true,
- "requires": {
+ "dependencies": {
"istanbul-lib-coverage": "^3.0.0",
- "make-dir": "^3.0.0",
+ "make-dir": "^4.0.0",
"supports-color": "^7.1.0"
},
- "dependencies": {
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
+ "engines": {
+ "node": ">=10"
}
},
- "istanbul-lib-source-maps": {
+ "node_modules/istanbul-lib-report/node_modules/make-dir": {
"version": "4.0.0",
- "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz",
- "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
+ "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
"dev": true,
- "requires": {
+ "dependencies": {
"debug": "^4.1.1",
"istanbul-lib-coverage": "^3.0.0",
"source-map": "^0.6.1"
},
- "dependencies": {
- "debug": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
- "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
- "dev": true,
- "requires": {
- "ms": "^2.1.1"
- }
- }
+ "engines": {
+ "node": ">=10"
}
},
- "istanbul-reports": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz",
- "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==",
+ "node_modules/istanbul-reports": {
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz",
+ "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==",
"dev": true,
- "requires": {
+ "dependencies": {
"html-escaper": "^2.0.0",
"istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "jest": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest/-/jest-26.0.1.tgz",
- "integrity": "sha512-29Q54kn5Bm7ZGKIuH2JRmnKl85YRigp0o0asTc6Sb6l2ch1DCXIeZTLLFy9ultJvhkTqbswF5DEx4+RlkmCxWg==",
+ "node_modules/jest": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.3.tgz",
+ "integrity": "sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==",
"dev": true,
- "requires": {
- "@jest/core": "^26.0.1",
+ "dependencies": {
+ "@jest/core": "^28.1.3",
+ "@jest/types": "^28.1.3",
"import-local": "^3.0.2",
- "jest-cli": "^26.0.1"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "graceful-fs": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
- "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "jest-cli": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.0.1.tgz",
- "integrity": "sha512-pFLfSOBcbG9iOZWaMK4Een+tTxi/Wcm34geqZEqrst9cZDkTQ1LZ2CnBrTlHWuYAiTMFr0EQeK52ScyFU8wK+w==",
- "dev": true,
- "requires": {
- "@jest/core": "^26.0.1",
- "@jest/test-result": "^26.0.1",
- "@jest/types": "^26.0.1",
- "chalk": "^4.0.0",
- "exit": "^0.1.2",
- "graceful-fs": "^4.2.4",
- "import-local": "^3.0.2",
- "is-ci": "^2.0.0",
- "jest-config": "^26.0.1",
- "jest-util": "^26.0.1",
- "jest-validate": "^26.0.1",
- "prompts": "^2.0.1",
- "yargs": "^15.3.1"
- }
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
+ "jest-cli": "^28.1.3"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
}
}
},
- "jest-changed-files": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.0.1.tgz",
- "integrity": "sha512-q8LP9Sint17HaE2LjxQXL+oYWW/WeeXMPE2+Op9X3mY8IEGFVc14xRxFjUuXUbcPAlDLhtWdIEt59GdQbn76Hw==",
+ "node_modules/jest-changed-files": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.1.3.tgz",
+ "integrity": "sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==",
"dev": true,
- "requires": {
- "@jest/types": "^26.0.1",
- "execa": "^4.0.0",
- "throat": "^5.0.0"
+ "dependencies": {
+ "execa": "^5.0.0",
+ "p-limit": "^3.1.0"
},
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+ }
+ },
+ "node_modules/jest-circus": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.3.tgz",
+ "integrity": "sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==",
+ "dev": true,
"dependencies": {
- "cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
- "dev": true,
- "requires": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- }
- },
- "execa": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.2.tgz",
- "integrity": "sha512-QI2zLa6CjGWdiQsmSkZoGtDx2N+cQIGb3yNolGTdjSQzydzLgYYf8LRuagp7S7fPimjcrzUDSUFd/MgzELMi4Q==",
- "dev": true,
- "requires": {
- "cross-spawn": "^7.0.0",
- "get-stream": "^5.0.0",
- "human-signals": "^1.1.1",
- "is-stream": "^2.0.0",
- "merge-stream": "^2.0.0",
- "npm-run-path": "^4.0.0",
- "onetime": "^5.1.0",
- "signal-exit": "^3.0.2",
- "strip-final-newline": "^2.0.0"
- }
- },
- "get-stream": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
- "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==",
- "dev": true,
- "requires": {
- "pump": "^3.0.0"
- }
- },
- "is-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
- "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
- "dev": true
- },
- "npm-run-path": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
- "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
- "dev": true,
- "requires": {
- "path-key": "^3.0.0"
- }
- },
- "path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
- "dev": true
- },
- "pump": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
- "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
- "dev": true,
- "requires": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
- "shebang-command": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
- "dev": true,
- "requires": {
- "shebang-regex": "^3.0.0"
- }
- },
- "shebang-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
- "dev": true
- },
- "which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "dev": true,
- "requires": {
- "isexe": "^2.0.0"
- }
+ "@jest/environment": "^28.1.3",
+ "@jest/expect": "^28.1.3",
+ "@jest/test-result": "^28.1.3",
+ "@jest/types": "^28.1.3",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "co": "^4.6.0",
+ "dedent": "^0.7.0",
+ "is-generator-fn": "^2.0.0",
+ "jest-each": "^28.1.3",
+ "jest-matcher-utils": "^28.1.3",
+ "jest-message-util": "^28.1.3",
+ "jest-runtime": "^28.1.3",
+ "jest-snapshot": "^28.1.3",
+ "jest-util": "^28.1.3",
+ "p-limit": "^3.1.0",
+ "pretty-format": "^28.1.3",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+ }
+ },
+ "node_modules/jest-cli": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz",
+ "integrity": "sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==",
+ "dev": true,
+ "dependencies": {
+ "@jest/core": "^28.1.3",
+ "@jest/test-result": "^28.1.3",
+ "@jest/types": "^28.1.3",
+ "chalk": "^4.0.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.9",
+ "import-local": "^3.0.2",
+ "jest-config": "^28.1.3",
+ "jest-util": "^28.1.3",
+ "jest-validate": "^28.1.3",
+ "prompts": "^2.0.1",
+ "yargs": "^17.3.1"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
}
}
},
- "jest-config": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.0.1.tgz",
- "integrity": "sha512-9mWKx2L1LFgOXlDsC4YSeavnblN6A4CPfXFiobq+YYLaBMymA/SczN7xYTSmLaEYHZOcB98UdoN4m5uNt6tztg==",
+ "node_modules/jest-config": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.3.tgz",
+ "integrity": "sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==",
"dev": true,
- "requires": {
- "@babel/core": "^7.1.0",
- "@jest/test-sequencer": "^26.0.1",
- "@jest/types": "^26.0.1",
- "babel-jest": "^26.0.1",
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@jest/test-sequencer": "^28.1.3",
+ "@jest/types": "^28.1.3",
+ "babel-jest": "^28.1.3",
"chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
"deepmerge": "^4.2.2",
- "glob": "^7.1.1",
- "graceful-fs": "^4.2.4",
- "jest-environment-jsdom": "^26.0.1",
- "jest-environment-node": "^26.0.1",
- "jest-get-type": "^26.0.0",
- "jest-jasmine2": "^26.0.1",
- "jest-regex-util": "^26.0.0",
- "jest-resolve": "^26.0.1",
- "jest-util": "^26.0.1",
- "jest-validate": "^26.0.1",
- "micromatch": "^4.0.2",
- "pretty-format": "^26.0.1"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
- "dev": true,
- "requires": {
- "fill-range": "^7.0.1"
- }
- },
- "chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
- "dev": true,
- "requires": {
- "to-regex-range": "^5.0.1"
- }
- },
- "graceful-fs": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
- "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true
- },
- "micromatch": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
- "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
- "dev": true,
- "requires": {
- "braces": "^3.0.1",
- "picomatch": "^2.0.5"
- }
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "jest-circus": "^28.1.3",
+ "jest-environment-node": "^28.1.3",
+ "jest-get-type": "^28.0.2",
+ "jest-regex-util": "^28.0.2",
+ "jest-resolve": "^28.1.3",
+ "jest-runner": "^28.1.3",
+ "jest-util": "^28.1.3",
+ "jest-validate": "^28.1.3",
+ "micromatch": "^4.0.4",
+ "parse-json": "^5.2.0",
+ "pretty-format": "^28.1.3",
+ "slash": "^3.0.0",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+ },
+ "peerDependencies": {
+ "@types/node": "*",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
},
- "to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "requires": {
- "is-number": "^7.0.0"
- }
+ "ts-node": {
+ "optional": true
}
}
},
- "jest-diff": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz",
- "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==",
+ "node_modules/jest-diff": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz",
+ "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==",
"dev": true,
- "requires": {
+ "dependencies": {
"chalk": "^4.0.0",
- "diff-sequences": "^26.0.0",
- "jest-get-type": "^26.0.0",
- "pretty-format": "^26.0.1"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
+ "diff-sequences": "^28.1.1",
+ "jest-get-type": "^28.0.2",
+ "pretty-format": "^28.1.3"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "jest-docblock": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz",
- "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==",
+ "node_modules/jest-docblock": {
+ "version": "28.1.1",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.1.1.tgz",
+ "integrity": "sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==",
"dev": true,
- "requires": {
+ "dependencies": {
"detect-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "jest-each": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.0.1.tgz",
- "integrity": "sha512-OTgJlwXCAR8NIWaXFL5DBbeS4QIYPuNASkzSwMCJO+ywo9BEa6TqkaSWsfR7VdbMLdgYJqSfQcIyjJCNwl5n4Q==",
+ "node_modules/jest-each": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.3.tgz",
+ "integrity": "sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==",
"dev": true,
- "requires": {
- "@jest/types": "^26.0.1",
+ "dependencies": {
+ "@jest/types": "^28.1.3",
"chalk": "^4.0.0",
- "jest-get-type": "^26.0.0",
- "jest-util": "^26.0.1",
- "pretty-format": "^26.0.1"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
+ "jest-get-type": "^28.0.2",
+ "jest-util": "^28.1.3",
+ "pretty-format": "^28.1.3"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "jest-environment-jsdom": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.0.1.tgz",
- "integrity": "sha512-u88NJa3aptz2Xix2pFhihRBAatwZHWwSiRLBDBQE1cdJvDjPvv7ZGA0NQBxWwDDn7D0g1uHqxM8aGgfA9Bx49g==",
+ "node_modules/jest-environment-node": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.3.tgz",
+ "integrity": "sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==",
"dev": true,
- "requires": {
- "@jest/environment": "^26.0.1",
- "@jest/fake-timers": "^26.0.1",
- "@jest/types": "^26.0.1",
- "jest-mock": "^26.0.1",
- "jest-util": "^26.0.1",
- "jsdom": "^16.2.2"
+ "dependencies": {
+ "@jest/environment": "^28.1.3",
+ "@jest/fake-timers": "^28.1.3",
+ "@jest/types": "^28.1.3",
+ "@types/node": "*",
+ "jest-mock": "^28.1.3",
+ "jest-util": "^28.1.3"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "jest-environment-node": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.0.1.tgz",
- "integrity": "sha512-4FRBWcSn5yVo0KtNav7+5NH5Z/tEgDLp7VRQVS5tCouWORxj+nI+1tOLutM07Zb2Qi7ja+HEDoOUkjBSWZg/IQ==",
+ "node_modules/jest-get-type": {
+ "version": "28.0.2",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz",
+ "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==",
"dev": true,
- "requires": {
- "@jest/environment": "^26.0.1",
- "@jest/fake-timers": "^26.0.1",
- "@jest/types": "^26.0.1",
- "jest-mock": "^26.0.1",
- "jest-util": "^26.0.1"
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "jest-get-type": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz",
- "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==",
- "dev": true
- },
- "jest-haste-map": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.0.1.tgz",
- "integrity": "sha512-J9kBl/EdjmDsvyv7CiyKY5+DsTvVOScenprz/fGqfLg/pm1gdjbwwQ98nW0t+OIt+f+5nAVaElvn/6wP5KO7KA==",
+ "node_modules/jest-haste-map": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz",
+ "integrity": "sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==",
"dev": true,
- "requires": {
- "@jest/types": "^26.0.1",
- "@types/graceful-fs": "^4.1.2",
+ "dependencies": {
+ "@jest/types": "^28.1.3",
+ "@types/graceful-fs": "^4.1.3",
+ "@types/node": "*",
"anymatch": "^3.0.3",
"fb-watchman": "^2.0.0",
- "fsevents": "^2.1.2",
- "graceful-fs": "^4.2.4",
- "jest-serializer": "^26.0.0",
- "jest-util": "^26.0.1",
- "jest-worker": "^26.0.0",
- "micromatch": "^4.0.2",
- "sane": "^4.0.3",
- "walker": "^1.0.7",
- "which": "^2.0.2"
- },
- "dependencies": {
- "anymatch": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
- "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
- "dev": true,
- "requires": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- }
- },
- "braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
- "dev": true,
- "requires": {
- "fill-range": "^7.0.1"
- }
- },
- "fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
- "dev": true,
- "requires": {
- "to-regex-range": "^5.0.1"
- }
- },
- "fsevents": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
- "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
- "dev": true,
- "optional": true
- },
- "graceful-fs": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
- "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
- "dev": true
- },
- "is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true
- },
- "micromatch": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
- "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
- "dev": true,
- "requires": {
- "braces": "^3.0.1",
- "picomatch": "^2.0.5"
- }
- },
- "normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true
- },
- "to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "requires": {
- "is-number": "^7.0.0"
- }
- },
- "which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "dev": true,
- "requires": {
- "isexe": "^2.0.0"
- }
- }
- }
- },
- "jest-jasmine2": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.0.1.tgz",
- "integrity": "sha512-ILaRyiWxiXOJ+RWTKupzQWwnPaeXPIoLS5uW41h18varJzd9/7I0QJGqg69fhTT1ev9JpSSo9QtalriUN0oqOg==",
- "dev": true,
- "requires": {
- "@babel/traverse": "^7.1.0",
- "@jest/environment": "^26.0.1",
- "@jest/source-map": "^26.0.0",
- "@jest/test-result": "^26.0.1",
- "@jest/types": "^26.0.1",
- "chalk": "^4.0.0",
- "co": "^4.6.0",
- "expect": "^26.0.1",
- "is-generator-fn": "^2.0.0",
- "jest-each": "^26.0.1",
- "jest-matcher-utils": "^26.0.1",
- "jest-message-util": "^26.0.1",
- "jest-runtime": "^26.0.1",
- "jest-snapshot": "^26.0.1",
- "jest-util": "^26.0.1",
- "pretty-format": "^26.0.1",
- "throat": "^5.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
+ "graceful-fs": "^4.2.9",
+ "jest-regex-util": "^28.0.2",
+ "jest-util": "^28.1.3",
+ "jest-worker": "^28.1.3",
+ "micromatch": "^4.0.4",
+ "walker": "^1.0.8"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "^2.3.2"
}
},
- "jest-leak-detector": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.0.1.tgz",
- "integrity": "sha512-93FR8tJhaYIWrWsbmVN1pQ9ZNlbgRpfvrnw5LmgLRX0ckOJ8ut/I35CL7awi2ecq6Ca4lL59bEK9hr7nqoHWPA==",
+ "node_modules/jest-leak-detector": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz",
+ "integrity": "sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==",
"dev": true,
- "requires": {
- "jest-get-type": "^26.0.0",
- "pretty-format": "^26.0.1"
+ "dependencies": {
+ "jest-get-type": "^28.0.2",
+ "pretty-format": "^28.1.3"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "jest-matcher-utils": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz",
- "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==",
+ "node_modules/jest-matcher-utils": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz",
+ "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==",
"dev": true,
- "requires": {
+ "dependencies": {
"chalk": "^4.0.0",
- "jest-diff": "^26.0.1",
- "jest-get-type": "^26.0.0",
- "pretty-format": "^26.0.1"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
+ "jest-diff": "^28.1.3",
+ "jest-get-type": "^28.0.2",
+ "pretty-format": "^28.1.3"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "jest-message-util": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz",
- "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==",
+ "node_modules/jest-message-util": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz",
+ "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==",
"dev": true,
- "requires": {
- "@babel/code-frame": "^7.0.0",
- "@jest/types": "^26.0.1",
- "@types/stack-utils": "^1.0.1",
+ "dependencies": {
+ "@babel/code-frame": "^7.12.13",
+ "@jest/types": "^28.1.3",
+ "@types/stack-utils": "^2.0.0",
"chalk": "^4.0.0",
- "graceful-fs": "^4.2.4",
- "micromatch": "^4.0.2",
+ "graceful-fs": "^4.2.9",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^28.1.3",
"slash": "^3.0.0",
- "stack-utils": "^2.0.2"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
- "dev": true,
- "requires": {
- "fill-range": "^7.0.1"
- }
- },
- "chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
- "dev": true,
- "requires": {
- "to-regex-range": "^5.0.1"
- }
- },
- "graceful-fs": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
- "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true
- },
- "micromatch": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
- "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
- "dev": true,
- "requires": {
- "braces": "^3.0.1",
- "picomatch": "^2.0.5"
- }
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- },
- "to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "requires": {
- "is-number": "^7.0.0"
- }
- }
+ "stack-utils": "^2.0.3"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "jest-mock": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz",
- "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==",
+ "node_modules/jest-mock": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz",
+ "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==",
"dev": true,
- "requires": {
- "@jest/types": "^26.0.1"
+ "dependencies": {
+ "@jest/types": "^28.1.3",
+ "@types/node": "*"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "jest-pnp-resolver": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz",
- "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==",
- "dev": true
+ "node_modules/jest-pnp-resolver": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
+ "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ },
+ "peerDependencies": {
+ "jest-resolve": "*"
+ },
+ "peerDependenciesMeta": {
+ "jest-resolve": {
+ "optional": true
+ }
+ }
},
- "jest-regex-util": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz",
- "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==",
- "dev": true
+ "node_modules/jest-regex-util": {
+ "version": "28.0.2",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz",
+ "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==",
+ "dev": true,
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+ }
},
- "jest-resolve": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz",
- "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==",
+ "node_modules/jest-resolve": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.3.tgz",
+ "integrity": "sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==",
"dev": true,
- "requires": {
- "@jest/types": "^26.0.1",
+ "dependencies": {
"chalk": "^4.0.0",
- "graceful-fs": "^4.2.4",
- "jest-pnp-resolver": "^1.2.1",
- "jest-util": "^26.0.1",
- "read-pkg-up": "^7.0.1",
- "resolve": "^1.17.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^28.1.3",
+ "jest-pnp-resolver": "^1.2.2",
+ "jest-util": "^28.1.3",
+ "jest-validate": "^28.1.3",
+ "resolve": "^1.20.0",
+ "resolve.exports": "^1.1.0",
"slash": "^3.0.0"
},
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "graceful-fs": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
- "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "jest-resolve-dependencies": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.0.1.tgz",
- "integrity": "sha512-9d5/RS/ft0vB/qy7jct/qAhzJsr6fRQJyGAFigK3XD4hf9kIbEH5gks4t4Z7kyMRhowU6HWm/o8ILqhaHdSqLw==",
+ "node_modules/jest-resolve-dependencies": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz",
+ "integrity": "sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==",
"dev": true,
- "requires": {
- "@jest/types": "^26.0.1",
- "jest-regex-util": "^26.0.0",
- "jest-snapshot": "^26.0.1"
+ "dependencies": {
+ "jest-regex-util": "^28.0.2",
+ "jest-snapshot": "^28.1.3"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "jest-runner": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.0.1.tgz",
- "integrity": "sha512-CApm0g81b49Znm4cZekYQK67zY7kkB4umOlI2Dx5CwKAzdgw75EN+ozBHRvxBzwo1ZLYZ07TFxkaPm+1t4d8jA==",
+ "node_modules/jest-runner": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.3.tgz",
+ "integrity": "sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==",
"dev": true,
- "requires": {
- "@jest/console": "^26.0.1",
- "@jest/environment": "^26.0.1",
- "@jest/test-result": "^26.0.1",
- "@jest/types": "^26.0.1",
+ "dependencies": {
+ "@jest/console": "^28.1.3",
+ "@jest/environment": "^28.1.3",
+ "@jest/test-result": "^28.1.3",
+ "@jest/transform": "^28.1.3",
+ "@jest/types": "^28.1.3",
+ "@types/node": "*",
"chalk": "^4.0.0",
- "exit": "^0.1.2",
- "graceful-fs": "^4.2.4",
- "jest-config": "^26.0.1",
- "jest-docblock": "^26.0.0",
- "jest-haste-map": "^26.0.1",
- "jest-jasmine2": "^26.0.1",
- "jest-leak-detector": "^26.0.1",
- "jest-message-util": "^26.0.1",
- "jest-resolve": "^26.0.1",
- "jest-runtime": "^26.0.1",
- "jest-util": "^26.0.1",
- "jest-worker": "^26.0.0",
- "source-map-support": "^0.5.6",
- "throat": "^5.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "graceful-fs": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
- "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "jest-runtime": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.0.1.tgz",
- "integrity": "sha512-Ci2QhYFmANg5qaXWf78T2Pfo6GtmIBn2rRaLnklRyEucmPccmCKvS9JPljcmtVamsdMmkyNkVFb9pBTD6si9Lw==",
- "dev": true,
- "requires": {
- "@jest/console": "^26.0.1",
- "@jest/environment": "^26.0.1",
- "@jest/fake-timers": "^26.0.1",
- "@jest/globals": "^26.0.1",
- "@jest/source-map": "^26.0.0",
- "@jest/test-result": "^26.0.1",
- "@jest/transform": "^26.0.1",
- "@jest/types": "^26.0.1",
- "@types/yargs": "^15.0.0",
+ "emittery": "^0.10.2",
+ "graceful-fs": "^4.2.9",
+ "jest-docblock": "^28.1.1",
+ "jest-environment-node": "^28.1.3",
+ "jest-haste-map": "^28.1.3",
+ "jest-leak-detector": "^28.1.3",
+ "jest-message-util": "^28.1.3",
+ "jest-resolve": "^28.1.3",
+ "jest-runtime": "^28.1.3",
+ "jest-util": "^28.1.3",
+ "jest-watcher": "^28.1.3",
+ "jest-worker": "^28.1.3",
+ "p-limit": "^3.1.0",
+ "source-map-support": "0.5.13"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+ }
+ },
+ "node_modules/jest-runtime": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz",
+ "integrity": "sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==",
+ "dev": true,
+ "dependencies": {
+ "@jest/environment": "^28.1.3",
+ "@jest/fake-timers": "^28.1.3",
+ "@jest/globals": "^28.1.3",
+ "@jest/source-map": "^28.1.2",
+ "@jest/test-result": "^28.1.3",
+ "@jest/transform": "^28.1.3",
+ "@jest/types": "^28.1.3",
"chalk": "^4.0.0",
+ "cjs-module-lexer": "^1.0.0",
"collect-v8-coverage": "^1.0.0",
- "exit": "^0.1.2",
+ "execa": "^5.0.0",
"glob": "^7.1.3",
- "graceful-fs": "^4.2.4",
- "jest-config": "^26.0.1",
- "jest-haste-map": "^26.0.1",
- "jest-message-util": "^26.0.1",
- "jest-mock": "^26.0.1",
- "jest-regex-util": "^26.0.0",
- "jest-resolve": "^26.0.1",
- "jest-snapshot": "^26.0.1",
- "jest-util": "^26.0.1",
- "jest-validate": "^26.0.1",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^28.1.3",
+ "jest-message-util": "^28.1.3",
+ "jest-mock": "^28.1.3",
+ "jest-regex-util": "^28.0.2",
+ "jest-resolve": "^28.1.3",
+ "jest-snapshot": "^28.1.3",
+ "jest-util": "^28.1.3",
"slash": "^3.0.0",
- "strip-bom": "^4.0.0",
- "yargs": "^15.3.1"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "graceful-fs": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
- "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
- }
- },
- "jest-serializer": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.0.0.tgz",
- "integrity": "sha512-sQGXLdEGWFAE4wIJ2ZaIDb+ikETlUirEOBsLXdoBbeLhTHkZUJwgk3+M8eyFizhM6le43PDCCKPA1hzkSDo4cQ==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.2.4"
+ "strip-bom": "^4.0.0"
},
- "dependencies": {
- "graceful-fs": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
- "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
- "dev": true
- }
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "jest-snapshot": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz",
- "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==",
+ "node_modules/jest-snapshot": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.3.tgz",
+ "integrity": "sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==",
"dev": true,
- "requires": {
- "@babel/types": "^7.0.0",
- "@jest/types": "^26.0.1",
- "@types/prettier": "^2.0.0",
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@babel/generator": "^7.7.2",
+ "@babel/plugin-syntax-typescript": "^7.7.2",
+ "@babel/traverse": "^7.7.2",
+ "@babel/types": "^7.3.3",
+ "@jest/expect-utils": "^28.1.3",
+ "@jest/transform": "^28.1.3",
+ "@jest/types": "^28.1.3",
+ "@types/babel__traverse": "^7.0.6",
+ "@types/prettier": "^2.1.5",
+ "babel-preset-current-node-syntax": "^1.0.0",
"chalk": "^4.0.0",
- "expect": "^26.0.1",
- "graceful-fs": "^4.2.4",
- "jest-diff": "^26.0.1",
- "jest-get-type": "^26.0.0",
- "jest-matcher-utils": "^26.0.1",
- "jest-message-util": "^26.0.1",
- "jest-resolve": "^26.0.1",
- "make-dir": "^3.0.0",
+ "expect": "^28.1.3",
+ "graceful-fs": "^4.2.9",
+ "jest-diff": "^28.1.3",
+ "jest-get-type": "^28.0.2",
+ "jest-haste-map": "^28.1.3",
+ "jest-matcher-utils": "^28.1.3",
+ "jest-message-util": "^28.1.3",
+ "jest-util": "^28.1.3",
"natural-compare": "^1.4.0",
- "pretty-format": "^26.0.1",
- "semver": "^7.3.2"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "graceful-fs": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
- "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "semver": {
- "version": "7.3.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
- "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
+ "pretty-format": "^28.1.3",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "jest-util": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz",
- "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==",
+ "node_modules/jest-util": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz",
+ "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==",
"dev": true,
- "requires": {
- "@jest/types": "^26.0.1",
+ "dependencies": {
+ "@jest/types": "^28.1.3",
+ "@types/node": "*",
"chalk": "^4.0.0",
- "graceful-fs": "^4.2.4",
- "is-ci": "^2.0.0",
- "make-dir": "^3.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "graceful-fs": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
- "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
+ "ci-info": "^3.2.0",
+ "graceful-fs": "^4.2.9",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "jest-validate": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.0.1.tgz",
- "integrity": "sha512-u0xRc+rbmov/VqXnX3DlkxD74rHI/CfS5xaV2VpeaVySjbb1JioNVOyly5b56q2l9ZKe7bVG5qWmjfctkQb0bA==",
+ "node_modules/jest-validate": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.3.tgz",
+ "integrity": "sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==",
"dev": true,
- "requires": {
- "@jest/types": "^26.0.1",
- "camelcase": "^6.0.0",
+ "dependencies": {
+ "@jest/types": "^28.1.3",
+ "camelcase": "^6.2.0",
"chalk": "^4.0.0",
- "jest-get-type": "^26.0.0",
+ "jest-get-type": "^28.0.2",
"leven": "^3.1.0",
- "pretty-format": "^26.0.1"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "camelcase": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz",
- "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==",
- "dev": true
- },
- "chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
+ "pretty-format": "^28.1.3"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+ }
+ },
+ "node_modules/jest-validate/node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "jest-watcher": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.0.1.tgz",
- "integrity": "sha512-pdZPydsS8475f89kGswaNsN3rhP6lnC3/QDCppP7bg1L9JQz7oU9Mb/5xPETk1RHDCWeqmVC47M4K5RR7ejxFw==",
+ "node_modules/jest-watcher": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz",
+ "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==",
"dev": true,
- "requires": {
- "@jest/test-result": "^26.0.1",
- "@jest/types": "^26.0.1",
+ "dependencies": {
+ "@jest/test-result": "^28.1.3",
+ "@jest/types": "^28.1.3",
+ "@types/node": "*",
"ansi-escapes": "^4.2.1",
"chalk": "^4.0.0",
- "jest-util": "^26.0.1",
+ "emittery": "^0.10.2",
+ "jest-util": "^28.1.3",
"string-length": "^4.0.1"
},
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
- "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "jest-worker": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.0.0.tgz",
- "integrity": "sha512-pPaYa2+JnwmiZjK9x7p9BoZht+47ecFCDFA/CJxspHzeDvQcfVBLWzCiWyo+EGrSiQMWZtCFo9iSvMZnAAo8vw==",
+ "node_modules/jest-worker": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz",
+ "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==",
"dev": true,
- "requires": {
+ "dependencies": {
+ "@types/node": "*",
"merge-stream": "^2.0.0",
- "supports-color": "^7.0.0"
+ "supports-color": "^8.0.0"
},
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+ }
+ },
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
"dependencies": {
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
- "joi": {
- "version": "17.10.1",
- "resolved": "https://registry.npmjs.org/joi/-/joi-17.10.1.tgz",
- "integrity": "sha512-vIiDxQKmRidUVp8KngT8MZSOcmRVm2zV7jbMjNYWuHcJWI0bUck3nRTGQjhpPlQenIQIBC5Vp9AhcnHbWQqafw==",
- "requires": {
- "@hapi/hoek": "^9.0.0",
- "@hapi/topo": "^5.0.0",
- "@sideway/address": "^4.1.3",
+ "node_modules/joi": {
+ "version": "17.12.2",
+ "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.2.tgz",
+ "integrity": "sha512-RonXAIzCiHLc8ss3Ibuz45u28GOsWE1UpfDXLbN/9NKbL4tCJf8TWYVKsoYuuh+sAUt7fsSNpA+r2+TBA6Wjmw==",
+ "dependencies": {
+ "@hapi/hoek": "^9.3.0",
+ "@hapi/topo": "^5.1.0",
+ "@sideway/address": "^4.1.5",
"@sideway/formula": "^3.0.1",
"@sideway/pinpoint": "^2.0.0"
- },
+ }
+ },
+ "node_modules/joi/node_modules/@hapi/hoek": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
+ "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
+ },
+ "node_modules/joi/node_modules/@hapi/topo": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
+ "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
"dependencies": {
- "@hapi/hoek": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
- "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
- },
- "@hapi/topo": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
- "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
- "requires": {
- "@hapi/hoek": "^9.0.0"
- }
- }
+ "@hapi/hoek": "^9.0.0"
}
},
- "js-tokens": {
+ "node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true
},
- "js-yaml": {
- "version": "3.14.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
- "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
- "requires": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
}
},
- "jsbn": {
+ "node_modules/jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
- "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
- },
- "jsdom": {
- "version": "16.2.2",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.2.2.tgz",
- "integrity": "sha512-pDFQbcYtKBHxRaP55zGXCJWgFHkDAYbKcsXEK/3Icu9nKYZkutUXfLBwbD+09XDutkYSHcgfQLZ0qvpAAm9mvg==",
- "dev": true,
- "requires": {
- "abab": "^2.0.3",
- "acorn": "^7.1.1",
- "acorn-globals": "^6.0.0",
- "cssom": "^0.4.4",
- "cssstyle": "^2.2.0",
- "data-urls": "^2.0.0",
- "decimal.js": "^10.2.0",
- "domexception": "^2.0.1",
- "escodegen": "^1.14.1",
- "html-encoding-sniffer": "^2.0.1",
- "is-potential-custom-element-name": "^1.0.0",
- "nwsapi": "^2.2.0",
- "parse5": "5.1.1",
- "request": "^2.88.2",
- "request-promise-native": "^1.0.8",
- "saxes": "^5.0.0",
- "symbol-tree": "^3.2.4",
- "tough-cookie": "^3.0.1",
- "w3c-hr-time": "^1.0.2",
- "w3c-xmlserializer": "^2.0.0",
- "webidl-conversions": "^6.0.0",
- "whatwg-encoding": "^1.0.5",
- "whatwg-mimetype": "^2.3.0",
- "whatwg-url": "^8.0.0",
- "ws": "^7.2.3",
- "xml-name-validator": "^3.0.0"
- },
- "dependencies": {
- "request": {
- "version": "2.88.2",
- "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
- "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
- "dev": true,
- "requires": {
- "aws-sign2": "~0.7.0",
- "aws4": "^1.8.0",
- "caseless": "~0.12.0",
- "combined-stream": "~1.0.6",
- "extend": "~3.0.2",
- "forever-agent": "~0.6.1",
- "form-data": "~2.3.2",
- "har-validator": "~5.1.3",
- "http-signature": "~1.2.0",
- "is-typedarray": "~1.0.0",
- "isstream": "~0.1.2",
- "json-stringify-safe": "~5.0.1",
- "mime-types": "~2.1.19",
- "oauth-sign": "~0.9.0",
- "performance-now": "^2.1.0",
- "qs": "~6.5.2",
- "safe-buffer": "^5.1.2",
- "tough-cookie": "~2.5.0",
- "tunnel-agent": "^0.6.0",
- "uuid": "^3.3.2"
- },
- "dependencies": {
- "tough-cookie": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
- "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
- "dev": true,
- "requires": {
- "psl": "^1.1.28",
- "punycode": "^2.1.1"
- }
- }
- }
- }
- }
+ "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg=="
},
- "jsesc": {
+ "node_modules/jsesc": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
- "dev": true
- },
- "json-buffer": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
- "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
- "dev": true
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
},
- "json-parse-better-errors": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
- "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
"dev": true
},
- "json-schema": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
- "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
- },
- "json-schema-ref-parser": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-6.1.0.tgz",
- "integrity": "sha512-pXe9H1m6IgIpXmE5JSb8epilNTGsmTb2iPohAXpOdhqGFbQjNeHHsZxU+C8w6T81GZxSPFLeUoqDJmzxx5IGuw==",
- "requires": {
- "call-me-maybe": "^1.0.1",
- "js-yaml": "^3.12.1",
- "ono": "^4.0.11"
- }
+ "node_modules/json-schema": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
},
- "json-schema-traverse": {
+ "node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
},
- "json-stringify-safe": {
+ "node_modules/json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
- "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
+ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
},
- "json5": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz",
- "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==",
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true,
- "requires": {
- "minimist": "^1.2.5"
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
}
},
- "jsonwebtoken": {
+ "node_modules/jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
- "requires": {
+ "dependencies": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
@@ -6248,440 +4052,320 @@
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^5.6.0"
+ },
+ "engines": {
+ "node": ">=4",
+ "npm": ">=1.4.28"
}
},
- "jsprim": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
- "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
- "requires": {
+ "node_modules/jsonwebtoken/node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/jsprim": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
+ "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
+ "dependencies": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
- "json-schema": "0.2.3",
+ "json-schema": "0.4.0",
"verror": "1.10.0"
+ },
+ "engines": {
+ "node": ">=0.6.0"
}
},
- "jwa": {
+ "node_modules/jwa": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
- "requires": {
+ "dependencies": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
- "jws": {
+ "node_modules/jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
- "requires": {
+ "dependencies": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
- "kareem": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz",
- "integrity": "sha512-l3hLhffs9zqoDe8zjmb/mAN4B8VT3L56EUvKNqLFVs9YlFA+zx7ke1DO8STAdDyYNkeSo1nKmjuvQeI12So8Xw=="
- },
- "keyv": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
- "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==",
- "dev": true,
- "requires": {
- "json-buffer": "3.0.0"
- }
- },
- "kind-of": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
- "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
- "dev": true
- },
- "kleur": {
+ "node_modules/kleur": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
"integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
- "dev": true
- },
- "latest-version": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz",
- "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==",
"dev": true,
- "requires": {
- "package-json": "^6.3.0"
+ "engines": {
+ "node": ">=6"
}
},
- "leven": {
+ "node_modules/leven": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
"integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
- "dev": true
- },
- "levn": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
- "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
"dev": true,
- "requires": {
- "prelude-ls": "~1.1.2",
- "type-check": "~0.3.2"
+ "engines": {
+ "node": ">=6"
}
},
- "lines-and-columns": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
- "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"dev": true
},
- "locate-path": {
+ "node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
- "requires": {
+ "dependencies": {
"p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "lodash": {
- "version": "4.17.15",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
- "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
- "lodash.get": {
+ "node_modules/lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
- "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
+ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
},
- "lodash.includes": {
+ "node_modules/lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
"integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
},
- "lodash.isboolean": {
+ "node_modules/lodash.isboolean": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
"integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
},
- "lodash.isequal": {
+ "node_modules/lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
- "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
+ "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
},
- "lodash.isinteger": {
+ "node_modules/lodash.isinteger": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
"integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
},
- "lodash.isnumber": {
+ "node_modules/lodash.isnumber": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
"integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
},
- "lodash.isplainobject": {
+ "node_modules/lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
},
- "lodash.isstring": {
+ "node_modules/lodash.isstring": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
"integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
},
- "lodash.once": {
+ "node_modules/lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
},
- "lodash.sortby": {
- "version": "4.7.0",
- "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
- "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
- "dev": true
- },
- "long": {
+ "node_modules/long": {
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
"integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q=="
},
- "lowercase-keys": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
- "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
- "dev": true
- },
- "lru-cache": {
- "version": "8.0.5",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz",
- "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA=="
+ "node_modules/lru-cache": {
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
+ "engines": {
+ "node": ">=12"
+ }
},
- "make-dir": {
+ "node_modules/make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
- "requires": {
+ "dependencies": {
"semver": "^6.0.0"
},
- "dependencies": {
- "semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
- }
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "makeerror": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz",
- "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=",
- "dev": true,
- "requires": {
- "tmpl": "1.0.x"
+ "node_modules/make-dir/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "bin": {
+ "semver": "bin/semver.js"
}
},
- "map-cache": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
- "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
- "dev": true
- },
- "map-visit": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
- "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+ "node_modules/makeerror": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
+ "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
"dev": true,
- "requires": {
- "object-visit": "^1.0.0"
+ "dependencies": {
+ "tmpl": "1.0.5"
}
},
- "memory-pager": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
- "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
- "optional": true
- },
- "merge-stream": {
+ "node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
"dev": true
},
- "micromatch": {
- "version": "3.1.10",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
- "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
- "dev": true,
- "requires": {
- "arr-diff": "^4.0.0",
- "array-unique": "^0.3.2",
- "braces": "^2.3.1",
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "extglob": "^2.0.4",
- "fragment-cache": "^0.2.1",
- "kind-of": "^6.0.2",
- "nanomatch": "^1.2.9",
- "object.pick": "^1.3.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.2"
- }
- },
- "mime-db": {
+ "node_modules/micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
},
- "mime-types": {
- "version": "2.1.24",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
- "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
- "requires": {
- "mime-db": "1.40.0"
- },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dependencies": {
- "mime-db": {
- "version": "1.40.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
- "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA=="
- }
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
}
},
- "mimic-fn": {
+ "node_modules/mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
- "dev": true
- },
- "mimic-response": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
- "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
- "dev": true
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
},
- "minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
- "requires": {
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dependencies": {
"brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
}
},
- "minimist": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
- "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
- "dev": true
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
},
- "minipass": {
+ "node_modules/minipass": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
- "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="
+ "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+ "engines": {
+ "node": ">=8"
+ }
},
- "minizlib": {
+ "node_modules/minizlib": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
- "requires": {
+ "dependencies": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
},
- "dependencies": {
- "minipass": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
- "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
- "requires": {
- "yallist": "^4.0.0"
- }
- }
+ "engines": {
+ "node": ">= 8"
}
},
- "mixin-deep": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
- "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
- "dev": true,
- "requires": {
- "for-in": "^1.0.2",
- "is-extendable": "^1.0.1"
- },
- "dependencies": {
- "is-extendable": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
- "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
- "dev": true,
- "requires": {
- "is-plain-object": "^2.0.4"
- }
- }
+ "node_modules/minizlib/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "mkdirp": {
+ "node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
- "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
- },
- "moment": {
- "version": "2.24.0",
- "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
- "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
- },
- "moment-timezone": {
- "version": "0.5.31",
- "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.31.tgz",
- "integrity": "sha512-+GgHNg8xRhMXfEbv81iDtrVeTcWt0kWmTEY1XQK14dICTXnWJnT0dxdlPspwqF3keKMVPXwayEsk1DI0AA/jdA==",
- "requires": {
- "moment": ">= 2.9.0"
- }
- },
- "mongodb": {
- "version": "3.5.7",
- "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.5.7.tgz",
- "integrity": "sha512-lMtleRT+vIgY/JhhTn1nyGwnSMmJkJELp+4ZbrjctrnBxuLbj6rmLuJFz8W2xUzUqWmqoyVxJLYuC58ZKpcTYQ==",
- "requires": {
- "bl": "^2.2.0",
- "bson": "^1.1.4",
- "denque": "^1.4.1",
- "require_optional": "^1.0.1",
- "safe-buffer": "^5.1.2",
- "saslprep": "^1.0.0"
- }
- },
- "mongoose": {
- "version": "5.9.16",
- "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.9.16.tgz",
- "integrity": "sha512-b4HNndgh+dacoLE/2SBF3iBBofeaKL+aGVZH7jnPRc2RXRCplX4sfH5sgoz03ryCSXJ+RQNIfqKAADt/ZBzPDA==",
- "requires": {
- "bson": "^1.1.4",
- "kareem": "2.3.1",
- "mongodb": "3.5.7",
- "mongoose-legacy-pluralize": "1.0.2",
- "mpath": "0.7.0",
- "mquery": "3.2.2",
- "ms": "2.1.2",
- "regexp-clone": "1.0.0",
- "safe-buffer": "5.1.2",
- "sift": "7.0.1",
- "sliced": "1.0.1"
- }
- },
- "mongoose-legacy-pluralize": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz",
- "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ=="
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
},
- "mpath": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.7.0.tgz",
- "integrity": "sha512-Aiq04hILxhz1L+f7sjGyn7IxYzWm1zLNNXcfhDtx04kZ2Gk7uvFdgZ8ts1cWa/6d0TQmag2yR8zSGZUmp0tFNg=="
+ "node_modules/moment": {
+ "version": "2.30.1",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
+ "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
+ "engines": {
+ "node": "*"
+ }
},
- "mquery": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.2.tgz",
- "integrity": "sha512-XB52992COp0KP230I3qloVUbkLUxJIu328HBP2t2EsxSFtf4W1HPSOBWOXf1bqxK4Xbb66lfMJ+Bpfd9/yZE1Q==",
- "requires": {
- "bluebird": "3.5.1",
- "debug": "3.1.0",
- "regexp-clone": "^1.0.0",
- "safe-buffer": "5.1.2",
- "sliced": "1.0.1"
- },
- "dependencies": {
- "bluebird": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
- "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA=="
- },
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "requires": {
- "ms": "2.0.0"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
- }
+ "node_modules/moment-timezone": {
+ "version": "0.5.45",
+ "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz",
+ "integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==",
+ "dependencies": {
+ "moment": "^2.29.4"
+ },
+ "engines": {
+ "node": "*"
}
},
- "ms": {
+ "node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
- "mysql2": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.6.0.tgz",
- "integrity": "sha512-EWUGAhv6SphezurlfI2Fpt0uJEWLmirrtQR7SkbTHFC+4/mJBrPiSzHESHKAWKG7ALVD6xaG/NBjjd1DGJGQQQ==",
- "requires": {
+ "node_modules/mysql2": {
+ "version": "3.9.2",
+ "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.2.tgz",
+ "integrity": "sha512-3Cwg/UuRkAv/wm6RhtPE5L7JlPB877vwSF6gfLAS68H+zhH+u5oa3AieqEd0D0/kC3W7qIhYbH419f7O9i/5nw==",
+ "dependencies": {
"denque": "^2.1.0",
"generate-function": "^2.3.1",
"iconv-lite": "^0.6.3",
@@ -6691,744 +4375,3041 @@
"seq-queue": "^0.0.5",
"sqlstring": "^2.3.2"
},
- "dependencies": {
- "denque": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
- "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="
- },
- "iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "requires": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- }
- }
+ "engines": {
+ "node": ">= 8.0"
+ }
+ },
+ "node_modules/mysql2/node_modules/lru-cache": {
+ "version": "8.0.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz",
+ "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==",
+ "engines": {
+ "node": ">=16.14"
}
},
- "named-placeholders": {
+ "node_modules/named-placeholders": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz",
"integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==",
- "requires": {
+ "dependencies": {
"lru-cache": "^7.14.1"
},
- "dependencies": {
- "lru-cache": {
- "version": "7.18.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
- "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="
- }
- }
- },
- "nanomatch": {
- "version": "1.2.13",
- "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
- "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
- "dev": true,
- "requires": {
- "arr-diff": "^4.0.0",
- "array-unique": "^0.3.2",
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "fragment-cache": "^0.2.1",
- "is-windows": "^1.0.2",
- "kind-of": "^6.0.2",
- "object.pick": "^1.3.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
+ "engines": {
+ "node": ">=12.0.0"
}
},
- "natural-compare": {
+ "node_modules/natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
- "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true
},
- "neo-async": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
- "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw=="
- },
- "nice-try": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
- "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
- "dev": true
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
},
- "node-addon-api": {
+ "node_modules/node-addon-api": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",
"integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA=="
},
- "node-fetch": {
+ "node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
- "requires": {
+ "dependencies": {
"whatwg-url": "^5.0.0"
},
- "dependencies": {
- "tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
- },
- "webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
- },
- "whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
- "requires": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
- }
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
}
}
},
- "node-int64": {
+ "node_modules/node-int64": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
- "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=",
+ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
"dev": true
},
- "node-modules-regexp": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz",
- "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=",
+ "node_modules/node-releases": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
+ "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
"dev": true
},
- "node-notifier": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-7.0.1.tgz",
- "integrity": "sha512-VkzhierE7DBmQEElhTGJIoiZa1oqRijOtgOlsXg32KrJRXsPy0NXFBqWGW/wTswnJlDCs5viRYaqWguqzsKcmg==",
- "dev": true,
- "optional": true,
- "requires": {
- "growly": "^1.3.0",
- "is-wsl": "^2.1.1",
- "semver": "^7.2.1",
- "shellwords": "^0.1.1",
- "uuid": "^7.0.3",
- "which": "^2.0.2"
- },
- "dependencies": {
- "semver": {
- "version": "7.3.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
- "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
- "dev": true,
- "optional": true
- },
- "uuid": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz",
- "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==",
- "dev": true,
- "optional": true
- },
- "which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "dev": true,
- "optional": true,
- "requires": {
- "isexe": "^2.0.0"
- }
- }
+ "node_modules/nodemailer": {
+ "version": "6.9.11",
+ "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.11.tgz",
+ "integrity": "sha512-UiAkgiERuG94kl/3bKfE8o10epvDnl0vokNEtZDPTq9BWzIl6EFT9336SbIT4oaTBD8NmmUTLsQyXHV82eXSWg==",
+ "engines": {
+ "node": ">=6.0.0"
}
},
- "nodemon": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.4.tgz",
- "integrity": "sha512-Ltced+hIfTmaS28Zjv1BM552oQ3dbwPqI4+zI0SLgq+wpJhSyqgYude/aZa/3i31VCQWMfXJVxvu86abcam3uQ==",
+ "node_modules/nodemon": {
+ "version": "2.0.22",
+ "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz",
+ "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==",
"dev": true,
- "requires": {
- "chokidar": "^3.2.2",
- "debug": "^3.2.6",
+ "dependencies": {
+ "chokidar": "^3.5.2",
+ "debug": "^3.2.7",
"ignore-by-default": "^1.0.1",
- "minimatch": "^3.0.4",
- "pstree.remy": "^1.1.7",
+ "minimatch": "^3.1.2",
+ "pstree.remy": "^1.1.8",
"semver": "^5.7.1",
+ "simple-update-notifier": "^1.0.7",
"supports-color": "^5.5.0",
"touch": "^3.1.0",
- "undefsafe": "^2.0.2",
- "update-notifier": "^4.0.0"
- }
- },
- "nopt": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
- "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
- "dev": true,
- "requires": {
- "abbrev": "1"
+ "undefsafe": "^2.0.5"
+ },
+ "bin": {
+ "nodemon": "bin/nodemon.js"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/nodemon"
}
},
- "normalize-package-data": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
- "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "node_modules/nodemon/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"dev": true,
- "requires": {
- "hosted-git-info": "^2.1.4",
- "resolve": "^1.10.0",
- "semver": "2 || 3 || 4 || 5",
- "validate-npm-package-license": "^3.0.1"
+ "dependencies": {
+ "ms": "^2.1.1"
}
},
- "normalize-path": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
- "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "node_modules/nodemon/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true,
- "requires": {
- "remove-trailing-separator": "^1.0.1"
+ "engines": {
+ "node": ">=4"
}
},
- "normalize-url": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
- "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
- "dev": true
- },
- "npm-run-path": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
- "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+ "node_modules/nodemon/node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"dev": true,
- "requires": {
- "path-key": "^2.0.0"
+ "bin": {
+ "semver": "bin/semver"
}
},
- "npmlog": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
- "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
- "requires": {
- "are-we-there-yet": "^2.0.0",
- "console-control-strings": "^1.1.0",
- "gauge": "^3.0.0",
- "set-blocking": "^2.0.0"
+ "node_modules/nodemon/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
}
},
- "nwsapi": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
- "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==",
- "dev": true
- },
- "oauth-sign": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
- "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
- },
- "object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
- },
- "object-copy": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
- "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
- "dev": true,
- "requires": {
- "copy-descriptor": "^0.1.0",
- "define-property": "^0.2.5",
- "kind-of": "^3.0.3"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
+ "node_modules/nopt": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
+ "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
+ "dependencies": {
+ "abbrev": "1"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": ">=6"
}
},
- "object-visit": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
- "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/npm": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/npm/-/npm-10.5.0.tgz",
+ "integrity": "sha512-Ejxwvfh9YnWVU2yA5FzoYLTW52vxHCz+MHrOFg9Cc8IFgF/6f5AGPAvb5WTay5DIUP1NIfN3VBZ0cLlGO0Ys+A==",
+ "bundleDependencies": [
+ "@isaacs/string-locale-compare",
+ "@npmcli/arborist",
+ "@npmcli/config",
+ "@npmcli/fs",
+ "@npmcli/map-workspaces",
+ "@npmcli/package-json",
+ "@npmcli/promise-spawn",
+ "@npmcli/run-script",
+ "@sigstore/tuf",
+ "abbrev",
+ "archy",
+ "cacache",
+ "chalk",
+ "ci-info",
+ "cli-columns",
+ "cli-table3",
+ "columnify",
+ "fastest-levenshtein",
+ "fs-minipass",
+ "glob",
+ "graceful-fs",
+ "hosted-git-info",
+ "ini",
+ "init-package-json",
+ "is-cidr",
+ "json-parse-even-better-errors",
+ "libnpmaccess",
+ "libnpmdiff",
+ "libnpmexec",
+ "libnpmfund",
+ "libnpmhook",
+ "libnpmorg",
+ "libnpmpack",
+ "libnpmpublish",
+ "libnpmsearch",
+ "libnpmteam",
+ "libnpmversion",
+ "make-fetch-happen",
+ "minimatch",
+ "minipass",
+ "minipass-pipeline",
+ "ms",
+ "node-gyp",
+ "nopt",
+ "normalize-package-data",
+ "npm-audit-report",
+ "npm-install-checks",
+ "npm-package-arg",
+ "npm-pick-manifest",
+ "npm-profile",
+ "npm-registry-fetch",
+ "npm-user-validate",
+ "npmlog",
+ "p-map",
+ "pacote",
+ "parse-conflict-json",
+ "proc-log",
+ "qrcode-terminal",
+ "read",
+ "semver",
+ "spdx-expression-parse",
+ "ssri",
+ "supports-color",
+ "tar",
+ "text-table",
+ "tiny-relative-date",
+ "treeverse",
+ "validate-npm-package-name",
+ "which",
+ "write-file-atomic"
+ ],
+ "dependencies": {
+ "@isaacs/string-locale-compare": "^1.1.0",
+ "@npmcli/arborist": "^7.2.1",
+ "@npmcli/config": "^8.0.2",
+ "@npmcli/fs": "^3.1.0",
+ "@npmcli/map-workspaces": "^3.0.4",
+ "@npmcli/package-json": "^5.0.0",
+ "@npmcli/promise-spawn": "^7.0.1",
+ "@npmcli/run-script": "^7.0.4",
+ "@sigstore/tuf": "^2.3.1",
+ "abbrev": "^2.0.0",
+ "archy": "~1.0.0",
+ "cacache": "^18.0.2",
+ "chalk": "^5.3.0",
+ "ci-info": "^4.0.0",
+ "cli-columns": "^4.0.0",
+ "cli-table3": "^0.6.3",
+ "columnify": "^1.6.0",
+ "fastest-levenshtein": "^1.0.16",
+ "fs-minipass": "^3.0.3",
+ "glob": "^10.3.10",
+ "graceful-fs": "^4.2.11",
+ "hosted-git-info": "^7.0.1",
+ "ini": "^4.1.1",
+ "init-package-json": "^6.0.0",
+ "is-cidr": "^5.0.3",
+ "json-parse-even-better-errors": "^3.0.1",
+ "libnpmaccess": "^8.0.1",
+ "libnpmdiff": "^6.0.3",
+ "libnpmexec": "^7.0.4",
+ "libnpmfund": "^5.0.1",
+ "libnpmhook": "^10.0.0",
+ "libnpmorg": "^6.0.1",
+ "libnpmpack": "^6.0.3",
+ "libnpmpublish": "^9.0.2",
+ "libnpmsearch": "^7.0.0",
+ "libnpmteam": "^6.0.0",
+ "libnpmversion": "^5.0.1",
+ "make-fetch-happen": "^13.0.0",
+ "minimatch": "^9.0.3",
+ "minipass": "^7.0.4",
+ "minipass-pipeline": "^1.2.4",
+ "ms": "^2.1.2",
+ "node-gyp": "^10.0.1",
+ "nopt": "^7.2.0",
+ "normalize-package-data": "^6.0.0",
+ "npm-audit-report": "^5.0.0",
+ "npm-install-checks": "^6.3.0",
+ "npm-package-arg": "^11.0.1",
+ "npm-pick-manifest": "^9.0.0",
+ "npm-profile": "^9.0.0",
+ "npm-registry-fetch": "^16.1.0",
+ "npm-user-validate": "^2.0.0",
+ "npmlog": "^7.0.1",
+ "p-map": "^4.0.0",
+ "pacote": "^17.0.6",
+ "parse-conflict-json": "^3.0.1",
+ "proc-log": "^3.0.0",
+ "qrcode-terminal": "^0.12.0",
+ "read": "^2.1.0",
+ "semver": "^7.6.0",
+ "spdx-expression-parse": "^3.0.1",
+ "ssri": "^10.0.5",
+ "supports-color": "^9.4.0",
+ "tar": "^6.2.0",
+ "text-table": "~0.2.0",
+ "tiny-relative-date": "^1.3.0",
+ "treeverse": "^3.0.0",
+ "validate-npm-package-name": "^5.0.0",
+ "which": "^4.0.0",
+ "write-file-atomic": "^5.0.1"
+ },
+ "bin": {
+ "npm": "bin/npm-cli.js",
+ "npx": "bin/npx-cli.js"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
"dev": true,
- "requires": {
- "isobject": "^3.0.0"
+ "dependencies": {
+ "path-key": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "object.pick": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
- "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
- "dev": true,
- "requires": {
- "isobject": "^3.0.1"
+ "node_modules/npm/node_modules/@colors/colors": {
+ "version": "1.5.0",
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=0.1.90"
}
},
- "once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
- "requires": {
- "wrappy": "1"
+ "node_modules/npm/node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
}
},
- "onetime": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
- "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
- "dev": true,
- "requires": {
- "mimic-fn": "^2.1.0"
+ "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": {
+ "version": "6.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
}
},
- "ono": {
- "version": "4.0.11",
- "resolved": "https://registry.npmjs.org/ono/-/ono-4.0.11.tgz",
- "integrity": "sha512-jQ31cORBFE6td25deYeD80wxKBMj+zBmHTrVxnc6CKhx8gho6ipmWM5zj/oeoqioZ99yqBls9Z/9Nss7J26G2g==",
- "requires": {
- "format-util": "^1.0.3"
+ "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": {
+ "version": "5.1.2",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "optionator": {
- "version": "0.8.3",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
- "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
- "dev": true,
- "requires": {
- "deep-is": "~0.1.3",
- "fast-levenshtein": "~2.0.6",
- "levn": "~0.3.0",
- "prelude-ls": "~1.1.2",
- "type-check": "~0.3.2",
- "word-wrap": "~1.2.3"
+ "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
- "p-cancelable": {
+ "node_modules/npm/node_modules/@isaacs/string-locale-compare": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
- "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
- "dev": true
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/@npmcli/agent": {
+ "version": "2.2.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "http-proxy-agent": "^7.0.0",
+ "https-proxy-agent": "^7.0.1",
+ "lru-cache": "^10.0.1",
+ "socks-proxy-agent": "^8.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/arborist": {
+ "version": "7.4.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@isaacs/string-locale-compare": "^1.1.0",
+ "@npmcli/fs": "^3.1.0",
+ "@npmcli/installed-package-contents": "^2.0.2",
+ "@npmcli/map-workspaces": "^3.0.2",
+ "@npmcli/metavuln-calculator": "^7.0.0",
+ "@npmcli/name-from-folder": "^2.0.0",
+ "@npmcli/node-gyp": "^3.0.0",
+ "@npmcli/package-json": "^5.0.0",
+ "@npmcli/query": "^3.1.0",
+ "@npmcli/run-script": "^7.0.2",
+ "bin-links": "^4.0.1",
+ "cacache": "^18.0.0",
+ "common-ancestor-path": "^1.0.1",
+ "hosted-git-info": "^7.0.1",
+ "json-parse-even-better-errors": "^3.0.0",
+ "json-stringify-nice": "^1.1.4",
+ "minimatch": "^9.0.0",
+ "nopt": "^7.0.0",
+ "npm-install-checks": "^6.2.0",
+ "npm-package-arg": "^11.0.1",
+ "npm-pick-manifest": "^9.0.0",
+ "npm-registry-fetch": "^16.0.0",
+ "npmlog": "^7.0.1",
+ "pacote": "^17.0.4",
+ "parse-conflict-json": "^3.0.0",
+ "proc-log": "^3.0.0",
+ "promise-all-reject-late": "^1.0.0",
+ "promise-call-limit": "^3.0.1",
+ "read-package-json-fast": "^3.0.2",
+ "semver": "^7.3.7",
+ "ssri": "^10.0.5",
+ "treeverse": "^3.0.0",
+ "walk-up-path": "^3.0.1"
+ },
+ "bin": {
+ "arborist": "bin/index.js"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/config": {
+ "version": "8.2.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/map-workspaces": "^3.0.2",
+ "ci-info": "^4.0.0",
+ "ini": "^4.1.0",
+ "nopt": "^7.0.0",
+ "proc-log": "^3.0.0",
+ "read-package-json-fast": "^3.0.2",
+ "semver": "^7.3.5",
+ "walk-up-path": "^3.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
},
- "p-each-series": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz",
- "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==",
- "dev": true
+ "node_modules/npm/node_modules/@npmcli/disparity-colors": {
+ "version": "3.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "ansi-styles": "^4.3.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
},
- "p-finally": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
- "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
- "dev": true
+ "node_modules/npm/node_modules/@npmcli/disparity-colors/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
},
- "p-limit": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
- "dev": true,
- "requires": {
- "p-try": "^2.0.0"
+ "node_modules/npm/node_modules/@npmcli/fs": {
+ "version": "3.1.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
- "p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "dev": true,
- "requires": {
- "p-limit": "^2.2.0"
+ "node_modules/npm/node_modules/@npmcli/git": {
+ "version": "5.0.4",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/promise-spawn": "^7.0.0",
+ "lru-cache": "^10.0.1",
+ "npm-pick-manifest": "^9.0.0",
+ "proc-log": "^3.0.0",
+ "promise-inflight": "^1.0.1",
+ "promise-retry": "^2.0.1",
+ "semver": "^7.3.5",
+ "which": "^4.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
}
},
- "p-try": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
- "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
- "dev": true
+ "node_modules/npm/node_modules/@npmcli/installed-package-contents": {
+ "version": "2.0.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "npm-bundled": "^3.0.0",
+ "npm-normalize-package-bin": "^3.0.0"
+ },
+ "bin": {
+ "installed-package-contents": "lib/index.js"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
},
- "package-json": {
- "version": "6.5.0",
- "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz",
- "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==",
- "dev": true,
- "requires": {
- "got": "^9.6.0",
- "registry-auth-token": "^4.0.0",
- "registry-url": "^5.0.0",
- "semver": "^6.2.0"
+ "node_modules/npm/node_modules/@npmcli/map-workspaces": {
+ "version": "3.0.4",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/name-from-folder": "^2.0.0",
+ "glob": "^10.2.2",
+ "minimatch": "^9.0.0",
+ "read-package-json-fast": "^3.0.0"
},
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/metavuln-calculator": {
+ "version": "7.0.0",
+ "inBundle": true,
+ "license": "ISC",
"dependencies": {
- "semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
- "dev": true
- }
+ "cacache": "^18.0.0",
+ "json-parse-even-better-errors": "^3.0.0",
+ "pacote": "^17.0.0",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/name-from-folder": {
+ "version": "2.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/node-gyp": {
+ "version": "3.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
- "parse-json": {
+ "node_modules/npm/node_modules/@npmcli/package-json": {
"version": "5.0.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz",
- "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==",
- "dev": true,
- "requires": {
- "@babel/code-frame": "^7.0.0",
- "error-ex": "^1.3.1",
- "json-parse-better-errors": "^1.0.1",
- "lines-and-columns": "^1.1.6"
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/git": "^5.0.0",
+ "glob": "^10.2.2",
+ "hosted-git-info": "^7.0.0",
+ "json-parse-even-better-errors": "^3.0.0",
+ "normalize-package-data": "^6.0.0",
+ "proc-log": "^3.0.0",
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
}
},
- "parse5": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
- "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
- "dev": true
+ "node_modules/npm/node_modules/@npmcli/promise-spawn": {
+ "version": "7.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "which": "^4.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
},
- "pascalcase": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
- "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
- "dev": true
+ "node_modules/npm/node_modules/@npmcli/query": {
+ "version": "3.1.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.10"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
},
- "path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true
+ "node_modules/npm/node_modules/@npmcli/run-script": {
+ "version": "7.0.4",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/node-gyp": "^3.0.0",
+ "@npmcli/package-json": "^5.0.0",
+ "@npmcli/promise-spawn": "^7.0.0",
+ "node-gyp": "^10.0.0",
+ "which": "^4.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
},
- "path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ "node_modules/npm/node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
},
- "path-key": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
- "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
- "dev": true
+ "node_modules/npm/node_modules/@sigstore/bundle": {
+ "version": "2.2.0",
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@sigstore/protobuf-specs": "^0.3.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
},
- "path-parse": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
- "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
- "dev": true
+ "node_modules/npm/node_modules/@sigstore/core": {
+ "version": "1.0.0",
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
},
- "performance-now": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
- "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+ "node_modules/npm/node_modules/@sigstore/protobuf-specs": {
+ "version": "0.3.0",
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
},
- "picomatch": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
- "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
- "dev": true
+ "node_modules/npm/node_modules/@sigstore/sign": {
+ "version": "2.2.3",
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@sigstore/bundle": "^2.2.0",
+ "@sigstore/core": "^1.0.0",
+ "@sigstore/protobuf-specs": "^0.3.0",
+ "make-fetch-happen": "^13.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
},
- "pirates": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz",
- "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==",
- "dev": true,
- "requires": {
- "node-modules-regexp": "^1.0.0"
+ "node_modules/npm/node_modules/@sigstore/tuf": {
+ "version": "2.3.1",
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@sigstore/protobuf-specs": "^0.3.0",
+ "tuf-js": "^2.2.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
}
},
- "pkg-dir": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
- "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
- "dev": true,
- "requires": {
- "find-up": "^4.0.0"
+ "node_modules/npm/node_modules/@sigstore/verify": {
+ "version": "1.1.0",
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@sigstore/bundle": "^2.2.0",
+ "@sigstore/core": "^1.0.0",
+ "@sigstore/protobuf-specs": "^0.3.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
}
},
- "posix-character-classes": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
- "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
- "dev": true
+ "node_modules/npm/node_modules/@tufjs/canonical-json": {
+ "version": "2.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
},
- "prelude-ls": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
- "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
- "dev": true
+ "node_modules/npm/node_modules/@tufjs/models": {
+ "version": "2.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "@tufjs/canonical-json": "2.0.0",
+ "minimatch": "^9.0.3"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
},
- "prepend-http": {
+ "node_modules/npm/node_modules/abbrev": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
- "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
- "dev": true
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
},
- "pretty-format": {
- "version": "26.0.1",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz",
- "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==",
- "dev": true,
- "requires": {
- "@jest/types": "^26.0.1",
- "ansi-regex": "^5.0.0",
- "ansi-styles": "^4.0.0",
- "react-is": "^16.12.0"
+ "node_modules/npm/node_modules/agent-base": {
+ "version": "7.1.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.4"
},
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/npm/node_modules/aggregate-error": {
+ "version": "3.1.0",
+ "inBundle": true,
+ "license": "MIT",
"dependencies": {
- "ansi-regex": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
- "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
- "dev": true
- },
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- }
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "process-nextick-args": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
- "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
+ "node_modules/npm/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
},
- "prompts": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz",
- "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==",
- "dev": true,
- "requires": {
- "kleur": "^3.0.3",
- "sisteransi": "^1.0.4"
+ "node_modules/npm/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "proxy-from-env": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
- "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ "node_modules/npm/node_modules/aproba": {
+ "version": "2.0.0",
+ "inBundle": true,
+ "license": "ISC"
},
- "psl": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz",
- "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw=="
+ "node_modules/npm/node_modules/archy": {
+ "version": "1.0.0",
+ "inBundle": true,
+ "license": "MIT"
},
- "pstree.remy": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
- "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
- "dev": true
+ "node_modules/npm/node_modules/are-we-there-yet": {
+ "version": "4.0.2",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
},
- "pump": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
- "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
- "requires": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
- "pumpify": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
- "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
- "requires": {
- "duplexify": "^3.6.0",
- "inherits": "^2.0.3",
- "pump": "^2.0.0"
+ "node_modules/npm/node_modules/balanced-match": {
+ "version": "1.0.2",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/bin-links": {
+ "version": "4.0.3",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "cmd-shim": "^6.0.0",
+ "npm-normalize-package-bin": "^3.0.0",
+ "read-cmd-shim": "^4.0.0",
+ "write-file-atomic": "^5.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
- "punycode": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
- "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
+ "node_modules/npm/node_modules/binary-extensions": {
+ "version": "2.2.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
},
- "pupa": {
+ "node_modules/npm/node_modules/brace-expansion": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.0.1.tgz",
- "integrity": "sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA==",
- "dev": true,
- "requires": {
- "escape-goat": "^2.0.0"
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
}
},
- "qs": {
- "version": "6.5.2",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
- "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
+ "node_modules/npm/node_modules/builtins": {
+ "version": "5.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.0.0"
+ }
},
- "rc": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
- "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
- "dev": true,
- "requires": {
- "deep-extend": "^0.6.0",
- "ini": "~1.3.0",
- "minimist": "^1.2.0",
- "strip-json-comments": "~2.0.1"
- },
+ "node_modules/npm/node_modules/cacache": {
+ "version": "18.0.2",
+ "inBundle": true,
+ "license": "ISC",
"dependencies": {
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- }
+ "@npmcli/fs": "^3.1.0",
+ "fs-minipass": "^3.0.0",
+ "glob": "^10.2.2",
+ "lru-cache": "^10.0.1",
+ "minipass": "^7.0.3",
+ "minipass-collect": "^2.0.1",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "p-map": "^4.0.0",
+ "ssri": "^10.0.0",
+ "tar": "^6.1.11",
+ "unique-filename": "^3.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
}
},
- "react-is": {
- "version": "16.13.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "node_modules/npm/node_modules/chalk": {
+ "version": "5.3.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/chownr": {
+ "version": "2.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/npm/node_modules/ci-info": {
+ "version": "4.0.0",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/cidr-regex": {
+ "version": "4.0.3",
+ "inBundle": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "ip-regex": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/npm/node_modules/clean-stack": {
+ "version": "2.2.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/npm/node_modules/cli-columns": {
+ "version": "4.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "string-width": "^4.2.3",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/npm/node_modules/cli-table3": {
+ "version": "0.6.3",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "string-width": "^4.2.0"
+ },
+ "engines": {
+ "node": "10.* || >= 12.*"
+ },
+ "optionalDependencies": {
+ "@colors/colors": "1.5.0"
+ }
+ },
+ "node_modules/npm/node_modules/clone": {
+ "version": "1.0.4",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/npm/node_modules/cmd-shim": {
+ "version": "6.0.2",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/color-convert": {
+ "version": "2.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/color-name": {
+ "version": "1.1.4",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/color-support": {
+ "version": "1.1.3",
+ "inBundle": true,
+ "license": "ISC",
+ "bin": {
+ "color-support": "bin.js"
+ }
+ },
+ "node_modules/npm/node_modules/columnify": {
+ "version": "1.6.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "strip-ansi": "^6.0.1",
+ "wcwidth": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/common-ancestor-path": {
+ "version": "1.0.1",
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/console-control-strings": {
+ "version": "1.1.0",
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/npm/node_modules/cross-spawn/node_modules/which": {
+ "version": "2.0.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/npm/node_modules/cssesc": {
+ "version": "3.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/npm/node_modules/debug": {
+ "version": "4.3.4",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/npm/node_modules/debug/node_modules/ms": {
+ "version": "2.1.2",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/defaults": {
+ "version": "1.0.4",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "clone": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm/node_modules/diff": {
+ "version": "5.2.0",
+ "inBundle": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/npm/node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/encoding": {
+ "version": "0.1.13",
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "iconv-lite": "^0.6.2"
+ }
+ },
+ "node_modules/npm/node_modules/env-paths": {
+ "version": "2.2.1",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/npm/node_modules/err-code": {
+ "version": "2.0.3",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/exponential-backoff": {
+ "version": "3.1.1",
+ "inBundle": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/npm/node_modules/fastest-levenshtein": {
+ "version": "1.0.16",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4.9.1"
+ }
+ },
+ "node_modules/npm/node_modules/foreground-child": {
+ "version": "3.1.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.0",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/fs-minipass": {
+ "version": "3.0.3",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/function-bind": {
+ "version": "1.1.2",
+ "inBundle": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/npm/node_modules/gauge": {
+ "version": "5.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "aproba": "^1.0.3 || ^2.0.0",
+ "color-support": "^1.1.3",
+ "console-control-strings": "^1.1.0",
+ "has-unicode": "^2.0.1",
+ "signal-exit": "^4.0.1",
+ "string-width": "^4.2.3",
+ "strip-ansi": "^6.0.1",
+ "wide-align": "^1.1.5"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/glob": {
+ "version": "10.3.10",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^2.3.5",
+ "minimatch": "^9.0.1",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
+ "path-scurry": "^1.10.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/has-unicode": {
+ "version": "2.0.1",
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/hasown": {
+ "version": "2.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/npm/node_modules/hosted-git-info": {
+ "version": "7.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "lru-cache": "^10.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/http-cache-semantics": {
+ "version": "4.1.1",
+ "inBundle": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/npm/node_modules/http-proxy-agent": {
+ "version": "7.0.2",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/npm/node_modules/https-proxy-agent": {
+ "version": "7.0.4",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.0.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/npm/node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/npm/node_modules/ignore-walk": {
+ "version": "6.0.4",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minimatch": "^9.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/npm/node_modules/indent-string": {
+ "version": "4.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/ini": {
+ "version": "4.1.1",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/init-package-json": {
+ "version": "6.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "npm-package-arg": "^11.0.0",
+ "promzard": "^1.0.0",
+ "read": "^2.0.0",
+ "read-package-json": "^7.0.0",
+ "semver": "^7.3.5",
+ "validate-npm-package-license": "^3.0.4",
+ "validate-npm-package-name": "^5.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/ip-address": {
+ "version": "9.0.5",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "jsbn": "1.1.0",
+ "sprintf-js": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/npm/node_modules/ip-address/node_modules/sprintf-js": {
+ "version": "1.1.3",
+ "inBundle": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/npm/node_modules/ip-regex": {
+ "version": "5.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm/node_modules/is-cidr": {
+ "version": "5.0.3",
+ "inBundle": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "cidr-regex": "4.0.3"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/npm/node_modules/is-core-module": {
+ "version": "2.13.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/npm/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/is-lambda": {
+ "version": "1.0.1",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/isexe": {
+ "version": "2.0.0",
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/jackspeak": {
+ "version": "2.3.6",
+ "inBundle": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/npm/node_modules/jsbn": {
+ "version": "1.1.0",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/json-parse-even-better-errors": {
+ "version": "3.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/json-stringify-nice": {
+ "version": "1.1.4",
+ "inBundle": true,
+ "license": "ISC",
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/jsonparse": {
+ "version": "1.3.1",
+ "engines": [
+ "node >= 0.2.0"
+ ],
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/just-diff": {
+ "version": "6.0.2",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/just-diff-apply": {
+ "version": "5.5.0",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/libnpmaccess": {
+ "version": "8.0.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "npm-package-arg": "^11.0.1",
+ "npm-registry-fetch": "^16.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmdiff": {
+ "version": "6.0.7",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/arborist": "^7.2.1",
+ "@npmcli/disparity-colors": "^3.0.0",
+ "@npmcli/installed-package-contents": "^2.0.2",
+ "binary-extensions": "^2.2.0",
+ "diff": "^5.1.0",
+ "minimatch": "^9.0.0",
+ "npm-package-arg": "^11.0.1",
+ "pacote": "^17.0.4",
+ "tar": "^6.2.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmexec": {
+ "version": "7.0.8",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/arborist": "^7.2.1",
+ "@npmcli/run-script": "^7.0.2",
+ "ci-info": "^4.0.0",
+ "npm-package-arg": "^11.0.1",
+ "npmlog": "^7.0.1",
+ "pacote": "^17.0.4",
+ "proc-log": "^3.0.0",
+ "read": "^2.0.0",
+ "read-package-json-fast": "^3.0.2",
+ "semver": "^7.3.7",
+ "walk-up-path": "^3.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmfund": {
+ "version": "5.0.5",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/arborist": "^7.2.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmhook": {
+ "version": "10.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "aproba": "^2.0.0",
+ "npm-registry-fetch": "^16.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmorg": {
+ "version": "6.0.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "aproba": "^2.0.0",
+ "npm-registry-fetch": "^16.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmpack": {
+ "version": "6.0.7",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/arborist": "^7.2.1",
+ "@npmcli/run-script": "^7.0.2",
+ "npm-package-arg": "^11.0.1",
+ "pacote": "^17.0.4"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmpublish": {
+ "version": "9.0.4",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "ci-info": "^4.0.0",
+ "normalize-package-data": "^6.0.0",
+ "npm-package-arg": "^11.0.1",
+ "npm-registry-fetch": "^16.0.0",
+ "proc-log": "^3.0.0",
+ "semver": "^7.3.7",
+ "sigstore": "^2.2.0",
+ "ssri": "^10.0.5"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmsearch": {
+ "version": "7.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "npm-registry-fetch": "^16.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmteam": {
+ "version": "6.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "aproba": "^2.0.0",
+ "npm-registry-fetch": "^16.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmversion": {
+ "version": "5.0.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/git": "^5.0.3",
+ "@npmcli/run-script": "^7.0.2",
+ "json-parse-even-better-errors": "^3.0.0",
+ "proc-log": "^3.0.0",
+ "semver": "^7.3.7"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/lru-cache": {
+ "version": "10.2.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "14 || >=16.14"
+ }
+ },
+ "node_modules/npm/node_modules/make-fetch-happen": {
+ "version": "13.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/agent": "^2.0.0",
+ "cacache": "^18.0.0",
+ "http-cache-semantics": "^4.1.1",
+ "is-lambda": "^1.0.1",
+ "minipass": "^7.0.2",
+ "minipass-fetch": "^3.0.0",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "negotiator": "^0.6.3",
+ "promise-retry": "^2.0.1",
+ "ssri": "^10.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/minimatch": {
+ "version": "9.0.3",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/minipass": {
+ "version": "7.0.4",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-collect": {
+ "version": "2.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-fetch": {
+ "version": "3.0.4",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "minipass": "^7.0.3",
+ "minipass-sized": "^1.0.3",
+ "minizlib": "^2.1.2"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ },
+ "optionalDependencies": {
+ "encoding": "^0.1.13"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-flush": {
+ "version": "1.0.5",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": {
+ "version": "3.3.6",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-json-stream": {
+ "version": "1.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "jsonparse": "^1.3.1",
+ "minipass": "^3.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-json-stream/node_modules/minipass": {
+ "version": "3.3.6",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-pipeline": {
+ "version": "1.2.4",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": {
+ "version": "3.3.6",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-sized": {
+ "version": "1.0.3",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": {
+ "version": "3.3.6",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/minizlib": {
+ "version": "2.1.2",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/npm/node_modules/minizlib/node_modules/minipass": {
+ "version": "3.3.6",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/mkdirp": {
+ "version": "1.0.4",
+ "inBundle": true,
+ "license": "MIT",
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/npm/node_modules/ms": {
+ "version": "2.1.3",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/mute-stream": {
+ "version": "1.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/negotiator": {
+ "version": "0.6.3",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/npm/node_modules/node-gyp": {
+ "version": "10.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "env-paths": "^2.2.0",
+ "exponential-backoff": "^3.1.1",
+ "glob": "^10.3.10",
+ "graceful-fs": "^4.2.6",
+ "make-fetch-happen": "^13.0.0",
+ "nopt": "^7.0.0",
+ "proc-log": "^3.0.0",
+ "semver": "^7.3.5",
+ "tar": "^6.1.2",
+ "which": "^4.0.0"
+ },
+ "bin": {
+ "node-gyp": "bin/node-gyp.js"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/nopt": {
+ "version": "7.2.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "abbrev": "^2.0.0"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/normalize-package-data": {
+ "version": "6.0.0",
+ "inBundle": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "hosted-git-info": "^7.0.0",
+ "is-core-module": "^2.8.1",
+ "semver": "^7.3.5",
+ "validate-npm-package-license": "^3.0.4"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-audit-report": {
+ "version": "5.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-bundled": {
+ "version": "3.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "npm-normalize-package-bin": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-install-checks": {
+ "version": "6.3.0",
+ "inBundle": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "semver": "^7.1.1"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-normalize-package-bin": {
+ "version": "3.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-package-arg": {
+ "version": "11.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "hosted-git-info": "^7.0.0",
+ "proc-log": "^3.0.0",
+ "semver": "^7.3.5",
+ "validate-npm-package-name": "^5.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-packlist": {
+ "version": "8.0.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "ignore-walk": "^6.0.4"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-pick-manifest": {
+ "version": "9.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "npm-install-checks": "^6.0.0",
+ "npm-normalize-package-bin": "^3.0.0",
+ "npm-package-arg": "^11.0.0",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-profile": {
+ "version": "9.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "npm-registry-fetch": "^16.0.0",
+ "proc-log": "^3.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-registry-fetch": {
+ "version": "16.1.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "make-fetch-happen": "^13.0.0",
+ "minipass": "^7.0.2",
+ "minipass-fetch": "^3.0.0",
+ "minipass-json-stream": "^1.0.1",
+ "minizlib": "^2.1.2",
+ "npm-package-arg": "^11.0.0",
+ "proc-log": "^3.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-user-validate": {
+ "version": "2.0.0",
+ "inBundle": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npmlog": {
+ "version": "7.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "are-we-there-yet": "^4.0.0",
+ "console-control-strings": "^1.1.0",
+ "gauge": "^5.0.0",
+ "set-blocking": "^2.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/p-map": {
+ "version": "4.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "aggregate-error": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm/node_modules/pacote": {
+ "version": "17.0.6",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/git": "^5.0.0",
+ "@npmcli/installed-package-contents": "^2.0.1",
+ "@npmcli/promise-spawn": "^7.0.0",
+ "@npmcli/run-script": "^7.0.0",
+ "cacache": "^18.0.0",
+ "fs-minipass": "^3.0.0",
+ "minipass": "^7.0.2",
+ "npm-package-arg": "^11.0.0",
+ "npm-packlist": "^8.0.0",
+ "npm-pick-manifest": "^9.0.0",
+ "npm-registry-fetch": "^16.0.0",
+ "proc-log": "^3.0.0",
+ "promise-retry": "^2.0.1",
+ "read-package-json": "^7.0.0",
+ "read-package-json-fast": "^3.0.0",
+ "sigstore": "^2.2.0",
+ "ssri": "^10.0.0",
+ "tar": "^6.1.11"
+ },
+ "bin": {
+ "pacote": "lib/bin.js"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/parse-conflict-json": {
+ "version": "3.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "json-parse-even-better-errors": "^3.0.0",
+ "just-diff": "^6.0.0",
+ "just-diff-apply": "^5.2.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/path-key": {
+ "version": "3.1.1",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/path-scurry": {
+ "version": "1.10.1",
+ "inBundle": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^9.1.1 || ^10.0.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/postcss-selector-parser": {
+ "version": "6.0.15",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/npm/node_modules/proc-log": {
+ "version": "3.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/promise-all-reject-late": {
+ "version": "1.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/promise-call-limit": {
+ "version": "3.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/promise-inflight": {
+ "version": "1.0.1",
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/promise-retry": {
+ "version": "2.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "err-code": "^2.0.2",
+ "retry": "^0.12.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/npm/node_modules/promzard": {
+ "version": "1.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "read": "^2.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/qrcode-terminal": {
+ "version": "0.12.0",
+ "inBundle": true,
+ "bin": {
+ "qrcode-terminal": "bin/qrcode-terminal.js"
+ }
+ },
+ "node_modules/npm/node_modules/read": {
+ "version": "2.1.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "mute-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/read-cmd-shim": {
+ "version": "4.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/read-package-json": {
+ "version": "7.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^10.2.2",
+ "json-parse-even-better-errors": "^3.0.0",
+ "normalize-package-data": "^6.0.0",
+ "npm-normalize-package-bin": "^3.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/read-package-json-fast": {
+ "version": "3.0.2",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "json-parse-even-better-errors": "^3.0.0",
+ "npm-normalize-package-bin": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/retry": {
+ "version": "0.12.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/npm/node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/npm/node_modules/semver": {
+ "version": "7.6.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/npm/node_modules/semver/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/npm/node_modules/set-blocking": {
+ "version": "2.0.0",
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/shebang-command": {
+ "version": "2.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/signal-exit": {
+ "version": "4.1.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/sigstore": {
+ "version": "2.2.2",
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@sigstore/bundle": "^2.2.0",
+ "@sigstore/core": "^1.0.0",
+ "@sigstore/protobuf-specs": "^0.3.0",
+ "@sigstore/sign": "^2.2.3",
+ "@sigstore/tuf": "^2.3.1",
+ "@sigstore/verify": "^1.1.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/smart-buffer": {
+ "version": "4.2.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/socks": {
+ "version": "2.8.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ip-address": "^9.0.5",
+ "smart-buffer": "^4.2.0"
+ },
+ "engines": {
+ "node": ">= 16.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/socks-proxy-agent": {
+ "version": "8.0.2",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.0.2",
+ "debug": "^4.3.4",
+ "socks": "^2.7.1"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/npm/node_modules/spdx-correct": {
+ "version": "3.2.0",
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/spdx-exceptions": {
+ "version": "2.5.0",
+ "inBundle": true,
+ "license": "CC-BY-3.0"
+ },
+ "node_modules/npm/node_modules/spdx-expression-parse": {
+ "version": "3.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/spdx-license-ids": {
+ "version": "3.0.17",
+ "inBundle": true,
+ "license": "CC0-1.0"
+ },
+ "node_modules/npm/node_modules/ssri": {
+ "version": "10.0.5",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/string-width": {
+ "version": "4.2.3",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/supports-color": {
+ "version": "9.4.0",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/tar": {
+ "version": "6.2.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^5.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/npm/node_modules/tar/node_modules/fs-minipass": {
+ "version": "2.1.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": {
+ "version": "3.3.6",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/tar/node_modules/minipass": {
+ "version": "5.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/text-table": {
+ "version": "0.2.0",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/tiny-relative-date": {
+ "version": "1.3.0",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/treeverse": {
+ "version": "3.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/tuf-js": {
+ "version": "2.2.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "@tufjs/models": "2.0.0",
+ "debug": "^4.3.4",
+ "make-fetch-happen": "^13.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/unique-filename": {
+ "version": "3.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "unique-slug": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/unique-slug": {
+ "version": "4.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "imurmurhash": "^0.1.4"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/validate-npm-package-license": {
+ "version": "3.0.4",
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/validate-npm-package-name": {
+ "version": "5.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "builtins": "^5.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/walk-up-path": {
+ "version": "3.0.1",
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/wcwidth": {
+ "version": "1.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "defaults": "^1.0.3"
+ }
+ },
+ "node_modules/npm/node_modules/which": {
+ "version": "4.0.0",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^3.1.1"
+ },
+ "bin": {
+ "node-which": "bin/which.js"
+ },
+ "engines": {
+ "node": "^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/which/node_modules/isexe": {
+ "version": "3.1.1",
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/npm/node_modules/wide-align": {
+ "version": "1.1.5",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^1.0.2 || 2 || 3 || 4"
+ }
+ },
+ "node_modules/npm/node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": {
+ "version": "6.0.1",
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": {
+ "version": "5.1.2",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/write-file-atomic": {
+ "version": "5.0.1",
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/yallist": {
+ "version": "4.0.0",
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npmlog": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
+ "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
+ "dependencies": {
+ "are-we-there-yet": "^2.0.0",
+ "console-control-strings": "^1.1.0",
+ "gauge": "^3.0.0",
+ "set-blocking": "^2.0.0"
+ }
+ },
+ "node_modules/oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/openapi-types": {
+ "version": "12.1.3",
+ "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz",
+ "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==",
+ "peer": true
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/p-locate/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "node_modules/performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"dev": true
},
- "read-pkg": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
- "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
- "requires": {
- "@types/normalize-package-data": "^2.4.0",
- "normalize-package-data": "^2.5.0",
- "parse-json": "^5.0.0",
- "type-fest": "^0.6.0"
+ "engines": {
+ "node": ">=8.6"
},
- "dependencies": {
- "type-fest": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
- "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
- "dev": true
- }
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
}
},
- "read-pkg-up": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
- "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
+ "node_modules/pirates": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
+ "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
"dev": true,
- "requires": {
- "find-up": "^4.1.0",
- "read-pkg": "^5.2.0",
- "type-fest": "^0.8.1"
+ "engines": {
+ "node": ">= 6"
}
},
- "readable-stream": {
- "version": "2.3.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
- "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "readdirp": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz",
- "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==",
+ "node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
"dev": true,
- "requires": {
- "picomatch": "^2.2.1"
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "regex-not": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
- "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "node_modules/pretty-format": {
+ "version": "28.1.3",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz",
+ "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==",
"dev": true,
- "requires": {
- "extend-shallow": "^3.0.2",
- "safe-regex": "^1.1.0"
+ "dependencies": {
+ "@jest/schemas": "^28.1.3",
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "regexp-clone": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz",
- "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw=="
- },
- "registry-auth-token": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.1.1.tgz",
- "integrity": "sha512-9bKS7nTl9+/A1s7tnPeGrUpRcVY+LUh7bfFgzpndALdPfXQBfQV77rQVtqgUV3ti4vc/Ik81Ex8UJDWDQ12zQA==",
+ "node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
"dev": true,
- "requires": {
- "rc": "^1.2.8"
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "registry-url": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz",
- "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==",
+ "node_modules/prompts": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
+ "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
"dev": true,
- "requires": {
- "rc": "^1.2.8"
+ "dependencies": {
+ "kleur": "^3.0.3",
+ "sisteransi": "^1.0.5"
+ },
+ "engines": {
+ "node": ">= 6"
}
},
- "remove-trailing-separator": {
+ "node_modules/proxy-from-env": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
- "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
- "dev": true
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
- "repeat-element": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
- "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+ "node_modules/psl": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
+ "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag=="
+ },
+ "node_modules/pstree.remy": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
+ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
"dev": true
},
- "repeat-string": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
- "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.5.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
+ "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
"dev": true
},
- "request": {
+ "node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/request": {
"version": "2.88.2",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
"integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
- "requires": {
+ "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
+ "dependencies": {
"aws-sign2": "~0.7.0",
"aws4": "^1.8.0",
"caseless": "~0.12.0",
@@ -7450,230 +7431,161 @@
"tunnel-agent": "^0.6.0",
"uuid": "^3.3.2"
},
- "dependencies": {
- "tough-cookie": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
- "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
- "requires": {
- "psl": "^1.1.28",
- "punycode": "^2.1.1"
- }
- }
- }
- },
- "request-promise-core": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz",
- "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==",
- "dev": true,
- "requires": {
- "lodash": "^4.17.15"
+ "engines": {
+ "node": ">= 6"
}
},
- "request-promise-native": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz",
- "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==",
- "dev": true,
- "requires": {
- "request-promise-core": "1.1.3",
- "stealthy-require": "^1.1.1",
- "tough-cookie": "^2.3.3"
- },
- "dependencies": {
- "tough-cookie": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
- "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
- "dev": true,
- "requires": {
- "psl": "^1.1.28",
- "punycode": "^2.1.1"
- }
- }
+ "node_modules/request/node_modules/form-data": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 0.12"
}
},
- "require-directory": {
+ "node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
- "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
- },
- "require-main-filename": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
- "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
- "dev": true
- },
- "require_optional": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
- "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==",
- "requires": {
- "resolve-from": "^2.0.0",
- "semver": "^5.1.0"
- },
- "dependencies": {
- "resolve-from": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz",
- "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c="
- }
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "resolve": {
- "version": "1.17.0",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
- "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
+ "node_modules/resolve": {
+ "version": "1.22.8",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
+ "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
"dev": true,
- "requires": {
- "path-parse": "^1.0.6"
+ "dependencies": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "resolve-cwd": {
+ "node_modules/resolve-cwd": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
"integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
"dev": true,
- "requires": {
+ "dependencies": {
"resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "resolve-from": {
+ "node_modules/resolve-from": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
"integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
- "dev": true
- },
- "resolve-url": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
- "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
- "dev": true
- },
- "responselike": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
- "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
"dev": true,
- "requires": {
- "lowercase-keys": "^1.0.0"
+ "engines": {
+ "node": ">=8"
}
},
- "ret": {
- "version": "0.1.15",
- "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
- "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
- "dev": true
+ "node_modules/resolve.exports": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz",
+ "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
},
- "retry-as-promised": {
+ "node_modules/retry-as-promised": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-3.2.0.tgz",
"integrity": "sha512-CybGs60B7oYU/qSQ6kuaFmRd9sTZ6oXSc0toqePvV74Ac6/IFZSI1ReFQmtCN+uvW1Mtqdwpvt/LGOiCBAY2Mg==",
- "requires": {
+ "dependencies": {
"any-promise": "^1.3.0"
}
},
- "rimraf": {
+ "node_modules/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "requires": {
+ "dependencies": {
"glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "rsvp": {
- "version": "4.8.5",
- "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz",
- "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==",
- "dev": true
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
- },
- "safe-regex": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
- "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
- "dev": true,
- "requires": {
- "ret": "~0.1.10"
- }
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
},
- "safer-buffer": {
+ "node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
- "sane": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz",
- "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==",
- "dev": true,
- "requires": {
- "@cnakazawa/watch": "^1.0.3",
- "anymatch": "^2.0.0",
- "capture-exit": "^2.0.0",
- "exec-sh": "^0.3.2",
- "execa": "^1.0.0",
- "fb-watchman": "^2.0.0",
- "micromatch": "^3.1.4",
- "minimist": "^1.1.1",
- "walker": "~1.0.5"
- }
- },
- "saslprep": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
- "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
- "optional": true,
- "requires": {
- "sparse-bitfield": "^3.0.3"
- }
- },
- "saxes": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
- "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==",
- "dev": true,
- "requires": {
- "xmlchars": "^2.2.0"
+ "node_modules/semver": {
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
+ "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
}
},
- "semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
- },
- "semver-diff": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz",
- "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==",
- "dev": true,
- "requires": {
- "semver": "^6.3.0"
- },
+ "node_modules/semver/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dependencies": {
- "semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
- "dev": true
- }
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
}
},
- "seq-queue": {
+ "node_modules/seq-queue": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz",
"integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="
},
- "sequelize": {
- "version": "5.21.11",
- "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-5.21.11.tgz",
- "integrity": "sha512-ZJw3Hp+NS7iHcTz4fHlKvIBm4I7xYibYRCP4HhSyMB26xgqFYFOXTaeWbHD2UUwAFaksTLw5ntzfpA9kE33SVA==",
- "requires": {
+ "node_modules/sequelize": {
+ "version": "5.22.5",
+ "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-5.22.5.tgz",
+ "integrity": "sha512-ySIHof18sJbeVG4zjEvsDL490cd9S14/IhkCrZR/g0C/FPlZq1AzEJVeSAo++9/sgJH2eERltAIGqYQNgVqX/A==",
+ "deprecated": "Please update to v6 or higher! A migration guide can be found here: https://sequelize.org/v6/manual/upgrade-to-v6.html",
+ "dependencies": {
"bluebird": "^3.5.0",
"cls-bluebird": "^2.1.0",
"debug": "^4.1.1",
@@ -7686,351 +7598,158 @@
"semver": "^6.3.0",
"sequelize-pool": "^2.3.0",
"toposort-class": "^1.0.1",
- "uuid": "^3.3.3",
- "validator": "^10.11.0",
+ "uuid": "^8.3.2",
+ "validator": "^13.7.0",
"wkx": "^0.4.8"
},
- "dependencies": {
- "debug": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
- "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
- "requires": {
- "ms": "^2.1.1"
- }
- },
- "semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
- }
+ "engines": {
+ "node": ">=6.0.0"
}
},
- "sequelize-mock": {
+ "node_modules/sequelize-mock": {
"version": "0.10.2",
"resolved": "https://registry.npmjs.org/sequelize-mock/-/sequelize-mock-0.10.2.tgz",
"integrity": "sha512-Vu95by/Bmhcx9PHKlZe+w7/7zw1AycV/SeevxQ5lDokAb50H7Kaf2SkjK5mqKxHWX6y/ICZ8JEfyMOg0nd1M2w==",
"dev": true,
- "requires": {
+ "dependencies": {
"bluebird": "^3.4.6",
"inflection": "^1.10.0",
"lodash": "^4.16.4"
}
},
- "sequelize-pool": {
+ "node_modules/sequelize-pool": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-2.3.0.tgz",
- "integrity": "sha512-Ibz08vnXvkZ8LJTiUOxRcj1Ckdn7qafNZ2t59jYHMX1VIebTAOYefWdRYFt6z6+hy52WGthAHAoLc9hvk3onqA=="
+ "integrity": "sha512-Ibz08vnXvkZ8LJTiUOxRcj1Ckdn7qafNZ2t59jYHMX1VIebTAOYefWdRYFt6z6+hy52WGthAHAoLc9hvk3onqA==",
+ "engines": {
+ "node": ">= 6.0.0"
+ }
},
- "set-blocking": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
- "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
+ "node_modules/sequelize/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
},
- "set-value": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
- "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
- "dev": true,
- "requires": {
- "extend-shallow": "^2.0.1",
- "is-extendable": "^0.1.1",
- "is-plain-object": "^2.0.3",
- "split-string": "^3.0.1"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
+ "node_modules/sequelize/node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "bin": {
+ "uuid": "dist/bin/uuid"
}
},
- "shebang-command": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
- "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "node_modules/set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
- "requires": {
- "shebang-regex": "^1.0.0"
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "shebang-regex": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
- "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
- "dev": true
- },
- "shellwords": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
- "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true,
- "optional": true
+ "engines": {
+ "node": ">=8"
+ }
},
- "shimmer": {
+ "node_modules/shimmer": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz",
"integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw=="
},
- "sift": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/sift/-/sift-7.0.1.tgz",
- "integrity": "sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g=="
+ "node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
},
- "signal-exit": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
- "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
+ "node_modules/simple-update-notifier": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz",
+ "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==",
+ "dev": true,
+ "dependencies": {
+ "semver": "~7.0.0"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/simple-update-notifier/node_modules/semver": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
+ "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
},
- "sisteransi": {
+ "node_modules/sisteransi": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
"integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
"dev": true
},
- "slash": {
+ "node_modules/slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
- "dev": true
- },
- "sliced": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
- "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
- },
- "snapdragon": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
- "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
- "dev": true,
- "requires": {
- "base": "^0.11.1",
- "debug": "^2.2.0",
- "define-property": "^0.2.5",
- "extend-shallow": "^2.0.1",
- "map-cache": "^0.2.2",
- "source-map": "^0.5.6",
- "source-map-resolve": "^0.5.0",
- "use": "^3.1.0"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
- "dev": true
- },
- "source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
- "dev": true
- }
- }
- },
- "snapdragon-node": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
- "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
- "dev": true,
- "requires": {
- "define-property": "^1.0.0",
- "isobject": "^3.0.0",
- "snapdragon-util": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- }
- }
- },
- "snapdragon-util": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
- "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
"dev": true,
- "requires": {
- "kind-of": "^3.2.0"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
+ "engines": {
+ "node": ">=8"
}
},
- "source-map": {
+ "node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- },
- "source-map-resolve": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
- "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
- "dev": true,
- "requires": {
- "atob": "^2.1.1",
- "decode-uri-component": "^0.2.0",
- "resolve-url": "^0.2.1",
- "source-map-url": "^0.4.0",
- "urix": "^0.1.0"
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "source-map-support": {
- "version": "0.5.19",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
- "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+ "node_modules/source-map-support": {
+ "version": "0.5.13",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
+ "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
"dev": true,
- "requires": {
+ "dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
- "source-map-url": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
- "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
- "dev": true
- },
- "sparse-bitfield": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
- "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
- "optional": true,
- "requires": {
- "memory-pager": "^1.0.2"
- }
- },
- "spdx-correct": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
- "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
- "dev": true,
- "requires": {
- "spdx-expression-parse": "^3.0.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "spdx-exceptions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
- "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
- "dev": true
- },
- "spdx-expression-parse": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
- "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
- "dev": true,
- "requires": {
- "spdx-exceptions": "^2.1.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "spdx-license-ids": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz",
- "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==",
- "dev": true
- },
- "split-string": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
- "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
- "dev": true,
- "requires": {
- "extend-shallow": "^3.0.0"
- }
- },
- "sprintf-js": {
+ "node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true
},
- "sqlstring": {
+ "node_modules/sqlstring": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz",
- "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg=="
+ "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
},
- "sshpk": {
- "version": "1.16.1",
- "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
- "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
- "requires": {
+ "node_modules/sshpk": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz",
+ "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==",
+ "dependencies": {
"asn1": "~0.2.3",
"assert-plus": "^1.0.0",
"bcrypt-pbkdf": "^1.0.0",
@@ -8040,906 +7759,629 @@
"jsbn": "~0.1.0",
"safer-buffer": "^2.0.2",
"tweetnacl": "~0.14.0"
+ },
+ "bin": {
+ "sshpk-conv": "bin/sshpk-conv",
+ "sshpk-sign": "bin/sshpk-sign",
+ "sshpk-verify": "bin/sshpk-verify"
+ },
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "stack-utils": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz",
- "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==",
+ "node_modules/stack-utils": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
+ "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
"dev": true,
- "requires": {
+ "dependencies": {
"escape-string-regexp": "^2.0.0"
},
- "dependencies": {
- "escape-string-regexp": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
- "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
- "dev": true
- }
+ "engines": {
+ "node": ">=10"
}
},
- "static-extend": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
- "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
- "dev": true,
- "requires": {
- "define-property": "^0.2.5",
- "object-copy": "^0.1.0"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- }
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
}
},
- "stealthy-require": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
- "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
- "dev": true
- },
- "stream-shift": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
- "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ=="
- },
- "string-length": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz",
- "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==",
+ "node_modules/string-length": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
+ "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
"dev": true,
- "requires": {
+ "dependencies": {
"char-regex": "^1.0.2",
"strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
}
},
- "string-width": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
- "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
- "requires": {
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.0"
+ "strip-ansi": "^6.0.1"
},
- "dependencies": {
- "is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
- }
- }
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "requires": {
- "safe-buffer": "~5.1.0"
+ "engines": {
+ "node": ">=8"
}
},
- "strip-ansi": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
- "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
- "requires": {
- "ansi-regex": "^5.0.0"
- },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dependencies": {
- "ansi-regex": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
- "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
- }
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "strip-bom": {
+ "node_modules/strip-bom": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
"integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
- "dev": true
- },
- "strip-eof": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
- "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
- "dev": true
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
},
- "strip-final-newline": {
+ "node_modules/strip-final-newline": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
- "dev": true
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
},
- "strip-json-comments": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
- "dev": true
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
},
- "supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "requires": {
- "has-flag": "^3.0.0"
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "supports-hyperlinks": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz",
- "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==",
+ "node_modules/supports-hyperlinks": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz",
+ "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==",
"dev": true,
- "requires": {
+ "dependencies": {
"has-flag": "^4.0.0",
"supports-color": "^7.0.0"
},
- "dependencies": {
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
+ "engines": {
+ "node": ">=8"
}
},
- "swagger-methods": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/swagger-methods/-/swagger-methods-1.0.8.tgz",
- "integrity": "sha512-G6baCwuHA+C5jf4FNOrosE4XlmGsdjbOjdBK4yuiDDj/ro9uR4Srj3OR84oQMT8F3qKp00tYNv0YN730oTHPZA=="
- },
- "swagger-parser": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/swagger-parser/-/swagger-parser-4.0.2.tgz",
- "integrity": "sha512-hKslog8LhsXICJ1sMLsA8b8hQ3oUEX0457aLCFJc4zz6m8drmnCtyjbVqS5HycaKFOKVolJc2wFoe8KDPWfp4g==",
- "requires": {
- "call-me-maybe": "^1.0.1",
- "debug": "^3.1.0",
- "json-schema-ref-parser": "^4.1.0",
- "ono": "^4.0.3",
- "swagger-methods": "^1.0.4",
- "swagger-schema-official": "2.0.0-bab6bed",
- "z-schema": "^3.19.0"
- },
- "dependencies": {
- "json-schema-ref-parser": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-4.1.1.tgz",
- "integrity": "sha512-lByoCHZ6H2zgb6NtsXIqtzQ+6Ji7iVqnrhWxsXLhF+gXmgu6E8+ErpDxCMR439MUG1nfMjWI2HAoM8l0XgSNhw==",
- "requires": {
- "call-me-maybe": "^1.0.1",
- "debug": "^3.1.0",
- "js-yaml": "^3.10.0",
- "ono": "^4.0.3"
- }
- }
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "swagger-schema-official": {
- "version": "2.0.0-bab6bed",
- "resolved": "https://registry.npmjs.org/swagger-schema-official/-/swagger-schema-official-2.0.0-bab6bed.tgz",
- "integrity": "sha1-cAcEaNbSl3ylI3suUZyn0Gouo/0="
- },
- "swagger-ui-dist": {
- "version": "3.25.5",
- "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.25.5.tgz",
- "integrity": "sha512-JZ6dVQS2nPgVYW0+JIIxm84vvFbR/ole6xYJG2DcSdejDLt8ARqIhbZ4InL7RVsLdXpPirUMb7hf2z4Fzqesyw=="
+ "node_modules/swagger-parser": {
+ "version": "10.0.3",
+ "resolved": "https://registry.npmjs.org/swagger-parser/-/swagger-parser-10.0.3.tgz",
+ "integrity": "sha512-nF7oMeL4KypldrQhac8RyHerJeGPD1p2xDh900GPvc+Nk7nWP6jX2FcC7WmkinMoAmoO774+AFXcWsW8gMWEIg==",
+ "dependencies": {
+ "@apidevtools/swagger-parser": "10.0.3"
+ },
+ "engines": {
+ "node": ">=10"
+ }
},
- "symbol-tree": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
- "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
- "dev": true
+ "node_modules/swagger-ui-dist": {
+ "version": "5.11.10",
+ "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.11.10.tgz",
+ "integrity": "sha512-wAHf32iFqJCBkdQRBYB1pR8kJuliJbgCXcdgkU7GkDvrOfD2gVmyEwdTi9rERCur/OrufifnH5UecOzlQ07CYg=="
},
- "tar": {
+ "node_modules/tar": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz",
"integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==",
- "requires": {
+ "dependencies": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
"minipass": "^5.0.0",
"minizlib": "^2.1.1",
"mkdirp": "^1.0.3",
"yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
}
},
- "term-size": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz",
- "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==",
- "dev": true
- },
- "terminal-link": {
+ "node_modules/terminal-link": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
"integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==",
"dev": true,
- "requires": {
+ "dependencies": {
"ansi-escapes": "^4.2.1",
"supports-hyperlinks": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "test-exclude": {
+ "node_modules/test-exclude": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
"integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
"dev": true,
- "requires": {
+ "dependencies": {
"@istanbuljs/schema": "^0.1.2",
"glob": "^7.1.4",
"minimatch": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=8"
}
},
- "throat": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz",
- "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==",
- "dev": true
- },
- "tmpl": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz",
- "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=",
+ "node_modules/tmpl": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
+ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
"dev": true
},
- "to-fast-properties": {
+ "node_modules/to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
- "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
- "dev": true
- },
- "to-object-path": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
- "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
"dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
+ "engines": {
+ "node": ">=4"
}
},
- "to-readable-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
- "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==",
- "dev": true
- },
- "to-regex": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
- "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
- "requires": {
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "regex-not": "^1.0.2",
- "safe-regex": "^1.1.0"
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
}
},
- "to-regex-range": {
+ "node_modules/topo": {
"version": "2.1.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
- "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
- "dev": true,
- "requires": {
- "is-number": "^3.0.0",
- "repeat-string": "^1.6.1"
+ "resolved": "https://registry.npmjs.org/topo/-/topo-2.1.1.tgz",
+ "integrity": "sha512-ZPrPP5nwzZy1fw9abHQH2k+YarTgp9UMAztcB3MmlcZSif63Eg+az05p6wTDaZmnqpS3Mk7K+2W60iHarlz8Ug==",
+ "deprecated": "This module has moved and is now available at @hapi/topo. Please update your dependencies as this version is no longer maintained and may contain bugs and security issues.",
+ "dependencies": {
+ "hoek": "4.x.x"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/topo/node_modules/hoek": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.3.1.tgz",
+ "integrity": "sha512-v7E+yIjcHECn973i0xHm4kJkEpv3C8sbYS4344WXbzYqRyiDD7rjnnKo4hsJkejQBAFdRMUGNHySeSPKSH9Rqw==",
+ "deprecated": "This module has moved and is now available at @hapi/hoek. Please update your dependencies as this version is no longer maintained an may contain bugs and security issues.",
+ "engines": {
+ "node": ">=6.0.0"
}
},
- "toposort-class": {
+ "node_modules/toposort-class": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz",
- "integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg="
+ "integrity": "sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg=="
},
- "touch": {
+ "node_modules/touch": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
"integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
"dev": true,
- "requires": {
+ "dependencies": {
"nopt": "~1.0.10"
+ },
+ "bin": {
+ "nodetouch": "bin/nodetouch.js"
}
},
- "tough-cookie": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
- "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==",
+ "node_modules/touch/node_modules/nopt": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
+ "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
"dev": true,
- "requires": {
- "ip-regex": "^2.1.0",
- "psl": "^1.1.28",
- "punycode": "^2.1.1"
+ "dependencies": {
+ "abbrev": "1"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": "*"
}
},
- "tr46": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz",
- "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==",
- "dev": true,
- "requires": {
+ "node_modules/tough-cookie": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+ "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+ "dependencies": {
+ "psl": "^1.1.28",
"punycode": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.8"
}
},
- "tunnel-agent": {
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ },
+ "node_modules/tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
- "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
- "requires": {
+ "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+ "dependencies": {
"safe-buffer": "^5.0.1"
+ },
+ "engines": {
+ "node": "*"
}
},
- "tweetnacl": {
+ "node_modules/tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
- "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
- },
- "type-check": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
- "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
- "dev": true,
- "requires": {
- "prelude-ls": "~1.1.2"
- }
+ "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
},
- "type-detect": {
+ "node_modules/type-detect": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
- "dev": true
- },
- "type-fest": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
- "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
- "dev": true
- },
- "typedarray-to-buffer": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
- "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
"dev": true,
- "requires": {
- "is-typedarray": "^1.0.0"
+ "engines": {
+ "node": ">=4"
}
},
- "uglify-js": {
- "version": "3.6.3",
- "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.3.tgz",
- "integrity": "sha512-KfQUgOqTkLp2aZxrMbCuKCDGW9slFYu2A23A36Gs7sGzTLcRBDORdOi5E21KWHFIfkY8kzgi/Pr1cXCh0yIp5g==",
- "optional": true,
- "requires": {
- "commander": "~2.20.3",
- "source-map": "~0.6.1"
+ "node_modules/type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "undefsafe": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz",
- "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==",
- "dev": true,
- "requires": {
- "debug": "^2.2.0"
+ "node_modules/uglify-js": {
+ "version": "3.17.4",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz",
+ "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==",
+ "optional": true,
+ "bin": {
+ "uglifyjs": "bin/uglifyjs"
},
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
- "dev": true
- }
+ "engines": {
+ "node": ">=0.8.0"
}
},
- "underscore": {
+ "node_modules/undefsafe": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
+ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
+ "dev": true
+ },
+ "node_modules/underscore": {
"version": "1.13.6",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
"integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A=="
},
- "union-value": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
- "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
- "dev": true,
- "requires": {
- "arr-union": "^3.1.0",
- "get-value": "^2.0.6",
- "is-extendable": "^0.1.1",
- "set-value": "^2.0.1"
- }
+ "node_modules/undici-types": {
+ "version": "5.26.5",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
+ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
},
- "unique-string": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
- "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==",
+ "node_modules/update-browserslist-db": {
+ "version": "1.0.13",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
+ "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
"dev": true,
- "requires": {
- "crypto-random-string": "^2.0.0"
- }
- },
- "unset-value": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
- "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
- "dev": true,
- "requires": {
- "has-value": "^0.3.1",
- "isobject": "^3.0.0"
- },
- "dependencies": {
- "has-value": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
- "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
- "dev": true,
- "requires": {
- "get-value": "^2.0.3",
- "has-values": "^0.1.4",
- "isobject": "^2.0.0"
- },
- "dependencies": {
- "isobject": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
- "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
- "dev": true,
- "requires": {
- "isarray": "1.0.0"
- }
- }
- }
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
},
- "has-values": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
- "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
- "dev": true
- }
- }
- },
- "update-notifier": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.0.tgz",
- "integrity": "sha512-w3doE1qtI0/ZmgeoDoARmI5fjDoT93IfKgEGqm26dGUOh8oNpaSTsGNdYRN/SjOuo10jcJGwkEL3mroKzktkew==",
- "dev": true,
- "requires": {
- "boxen": "^4.2.0",
- "chalk": "^3.0.0",
- "configstore": "^5.0.1",
- "has-yarn": "^2.1.0",
- "import-lazy": "^2.1.0",
- "is-ci": "^2.0.0",
- "is-installed-globally": "^0.3.1",
- "is-npm": "^4.0.0",
- "is-yarn-global": "^0.3.0",
- "latest-version": "^5.0.0",
- "pupa": "^2.0.1",
- "semver-diff": "^3.1.1",
- "xdg-basedir": "^4.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
- "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
},
- "supports-color": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
- "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
}
+ ],
+ "dependencies": {
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
}
},
- "uri-js": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
- "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
- "requires": {
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dependencies": {
"punycode": "^2.1.0"
}
},
- "urix": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
- "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
- "dev": true
- },
- "url-parse-lax": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
- "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
- "dev": true,
- "requires": {
- "prepend-http": "^2.0.0"
- }
- },
- "use": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
- "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
- "dev": true
- },
- "util-deprecate": {
+ "node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
- "uuid": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz",
- "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ=="
+ "node_modules/uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+ "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
+ "bin": {
+ "uuid": "bin/uuid"
+ }
},
- "v8-to-istanbul": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz",
- "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==",
+ "node_modules/v8-to-istanbul": {
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz",
+ "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==",
"dev": true,
- "requires": {
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.12",
"@types/istanbul-lib-coverage": "^2.0.1",
- "convert-source-map": "^1.6.0",
- "source-map": "^0.7.3"
+ "convert-source-map": "^2.0.0"
},
- "dependencies": {
- "source-map": {
- "version": "0.7.3",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
- "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
- "dev": true
- }
+ "engines": {
+ "node": ">=10.12.0"
}
},
- "validate-npm-package-license": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
- "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
- "dev": true,
- "requires": {
- "spdx-correct": "^3.0.0",
- "spdx-expression-parse": "^3.0.0"
- }
+ "node_modules/v8-to-istanbul/node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true
},
- "validator": {
- "version": "10.11.0",
- "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz",
- "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw=="
+ "node_modules/validator": {
+ "version": "13.11.0",
+ "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz",
+ "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==",
+ "engines": {
+ "node": ">= 0.10"
+ }
},
- "verror": {
+ "node_modules/verror": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
- "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
- "requires": {
+ "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
+ "engines": [
+ "node >=0.6.0"
+ ],
+ "dependencies": {
"assert-plus": "^1.0.0",
"core-util-is": "1.0.2",
"extsprintf": "^1.2.0"
}
},
- "w3c-hr-time": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
- "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==",
- "dev": true,
- "requires": {
- "browser-process-hrtime": "^1.0.0"
- }
- },
- "w3c-xmlserializer": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz",
- "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==",
- "dev": true,
- "requires": {
- "xml-name-validator": "^3.0.0"
- }
- },
- "walker": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz",
- "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=",
+ "node_modules/walker": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
+ "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
"dev": true,
- "requires": {
- "makeerror": "1.0.x"
+ "dependencies": {
+ "makeerror": "1.0.12"
}
},
- "wcwidth": {
+ "node_modules/wcwidth": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
- "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=",
+ "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
"optional": true,
- "requires": {
+ "dependencies": {
"defaults": "^1.0.3"
}
},
- "webidl-conversions": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
- "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==",
- "dev": true
- },
- "whatwg-encoding": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
- "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==",
- "dev": true,
- "requires": {
- "iconv-lite": "0.4.24"
- }
- },
- "whatwg-mimetype": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
- "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==",
- "dev": true
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
},
- "whatwg-url": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz",
- "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==",
- "dev": true,
- "requires": {
- "lodash.sortby": "^4.7.0",
- "tr46": "^2.0.2",
- "webidl-conversions": "^5.0.0"
- },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dependencies": {
- "webidl-conversions": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz",
- "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==",
- "dev": true
- }
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
}
},
- "which": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
- "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
- "requires": {
+ "dependencies": {
"isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
}
},
- "which-module": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
- "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
- "dev": true
- },
- "wide-align": {
+ "node_modules/wide-align": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
- "requires": {
+ "dependencies": {
"string-width": "^1.0.2 || 2 || 3 || 4"
}
},
- "widest-line": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
- "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==",
- "dev": true,
- "requires": {
- "string-width": "^4.0.0"
- }
- },
- "wkx": {
+ "node_modules/wkx": {
"version": "0.4.8",
"resolved": "https://registry.npmjs.org/wkx/-/wkx-0.4.8.tgz",
"integrity": "sha512-ikPXMM9IR/gy/LwiOSqWlSL3X/J5uk9EO2hHNRXS41eTLXaUFEVw9fn/593jW/tE5tedNg8YjT5HkCa4FqQZyQ==",
- "requires": {
+ "dependencies": {
"@types/node": "*"
}
},
- "word-wrap": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
- "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
- "dev": true
+ "node_modules/wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="
},
- "wrap-ansi": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
- "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true,
- "requires": {
+ "dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
- "dependencies": {
- "ansi-styles": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
- "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
- "dev": true,
- "requires": {
- "@types/color-name": "^1.1.1",
- "color-convert": "^2.0.1"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- }
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
- "wrappy": {
+ "node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
- "write-file-atomic": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
- "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
+ "node_modules/write-file-atomic": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
+ "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
"dev": true,
- "requires": {
+ "dependencies": {
"imurmurhash": "^0.1.4",
- "is-typedarray": "^1.0.0",
- "signal-exit": "^3.0.2",
- "typedarray-to-buffer": "^3.1.5"
+ "signal-exit": "^3.0.7"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
- "ws": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz",
- "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==",
- "dev": true
- },
- "xdg-basedir": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz",
- "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==",
- "dev": true
- },
- "xml-name-validator": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
- "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
- "dev": true
- },
- "xmlchars": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
- "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
- "dev": true
- },
- "y18n": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
- "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
- "dev": true
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
},
- "yallist": {
+ "node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
- "yargs": {
- "version": "15.3.1",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz",
- "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==",
+ "node_modules/yargs": {
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
"dev": true,
- "requires": {
- "cliui": "^6.0.0",
- "decamelize": "^1.2.0",
- "find-up": "^4.1.0",
- "get-caller-file": "^2.0.1",
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
- "require-main-filename": "^2.0.0",
- "set-blocking": "^2.0.0",
- "string-width": "^4.2.0",
- "which-module": "^2.0.0",
- "y18n": "^4.0.0",
- "yargs-parser": "^18.1.1"
- }
- },
- "yargs-parser": {
- "version": "18.1.3",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
- "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
- "dev": true,
- "requires": {
- "camelcase": "^5.0.0",
- "decamelize": "^1.2.0"
- }
- },
- "z-schema": {
- "version": "3.25.1",
- "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.25.1.tgz",
- "integrity": "sha512-7tDlwhrBG+oYFdXNOjILSurpfQyuVgkRe3hB2q8TEssamDHB7BbLWYkYO98nTn0FibfdFroFKDjndbgufAgS/Q==",
- "requires": {
- "commander": "^2.7.1",
- "core-js": "^2.5.7",
- "lodash.get": "^4.0.0",
- "lodash.isequal": "^4.0.0",
- "validator": "^10.0.0"
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/z-schema": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz",
+ "integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==",
+ "dependencies": {
+ "lodash.get": "^4.4.2",
+ "lodash.isequal": "^4.5.0",
+ "validator": "^13.7.0"
+ },
+ "bin": {
+ "z-schema": "bin/z-schema"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "commander": "^9.4.1"
}
}
}
diff --git a/package.json b/package.json
index 5606170..5ab0ccf 100644
--- a/package.json
+++ b/package.json
@@ -12,31 +12,31 @@
"husky": "node ./node_modules/husky/lib/bin.js"
},
"dependencies": {
- "@hapi/boom": "^9.1.0",
- "@hapi/good": "^9.0.0",
- "@hapi/good-console": "^9.0.0",
- "@hapi/good-squeeze": "^6.0.0",
- "@hapi/hapi": "^20.0.0",
- "@hapi/inert": "^6.0.1",
+ "@hapi/boom": "^10.0.1",
+ "@hapi/hapi": "^21.3.2",
+ "@hapi/inert": "^7.1.0",
+ "@hapi/joi": "^17.1.1",
"@hapi/jwt": "^3.2.0",
- "@hapi/vision": "^6.0.0",
+ "@hapi/vision": "^7.0.3",
"axios": "^1.5.1",
"bcrypt": "^5.1.1",
- "blipp": "^4.0.1",
+ "blipp": "^4.0.2",
"dotenv": "^8.6.0",
- "hapi-swagger": "^13.0.2",
+ "hapi-cors": "^1.0.3",
+ "mysql2": "^3.6.0",
+ "hapi-swagger": "^17.2.1",
+ "install": "^0.13.0",
"joi": "^17.10.0",
"jsonwebtoken": "^8.5.1",
- "mongoose": "^5.9.16",
- "mysql2": "^3.6.0",
+ "nodemailer": "^6.9.7",
+ "npm": "^10.2.5",
"request": "^2.88.2",
- "require-directory": "^2.1.1",
"sequelize": "^5.21.11",
"underscore": "^1.13.6"
},
"devDependencies": {
"husky": "^8.0.3",
- "jest": "^26.0.1",
+ "jest": "^28.0.0",
"nodemon": "^2.0.4",
"sequelize-mock": "^0.10.2"
},
@@ -45,12 +45,10 @@
"npm": ">=6.12"
},
"jest": {
+ "collectCoverage": true,
"collectCoverageFrom": [
- "**/*.{js}",
- "!**/node_modules/**",
- "!**/vendor/**",
- "!**/coverage/**"
+ "lib/application/**/*.js"
],
- "testURL": "http://localhost/"
+ "coverageDirectory": "coverage"
}
}
diff --git a/scripts/insert_test_data.py b/scripts/insert_test_data.py
new file mode 100644
index 0000000..4c1f88f
--- /dev/null
+++ b/scripts/insert_test_data.py
@@ -0,0 +1,322 @@
+import random
+import requests
+import mysql.connector
+import faker
+
+
+def getRandomImageURL():
+ baseUrl = 'https://ozgrozer.github.io/100k-faces'
+ folder = random.randint(0, 9)
+ val = random.randint(0,999)
+ file = f"00{folder}{'000'[len(str(val)):] + str(val)}"
+
+ return f"{baseUrl}/0/{folder}/{file}.jpg"
+
+
+
+def insertUser(cursor,pseudo,password,bio):
+
+ try:
+ photo = getRandomImageURL()
+ user_id = None
+ date = faker.Faker().date_between(start_date='-1y', end_date='today')
+ data_to_insert = {
+ "pseudo": pseudo,
+ "alias": pseudo,
+ "password": password,
+ "email": f"{pseudo}.{pseudo}@gmail.com",
+ "photo": photo,
+ "bio": bio,
+ "confirmed": 1,
+ "id_role": 1,
+ "createdAt": date,
+ "updatedAt": date,
+ "is_private": 1 if random.random() <0.5 else 0
+ }
+ insert_query = """
+ INSERT INTO utilisateur
+ (pseudo, alias, password, email, photo, bio, confirmed, id_role,createdAt,updatedAt,is_private)
+ VALUES (%(pseudo)s, %(alias)s, %(password)s, %(email)s, %(photo)s, %(bio)s,%(confirmed)s, %(id_role)s,%(createdAt)s, %(updatedAt)s,%(is_private)s)
+ """
+ # Exécuter la requête d'insertion avec les données
+ cursor.execute(insert_query, data_to_insert)
+ # Récupérer l'ID de l'utilisateur créé
+ user_id = cursor.lastrowid
+ print("insert")
+ except Exception as err:
+ print(f"Erreur lors de l'insertion dans la base de données : {err}")
+
+ return user_id
+
+def insert_follow(cursor,ids,artists):
+ date = faker.Faker().date_between(start_date='-1y', end_date='today')
+ for artist in artists:
+ data_to_insert = {
+ "createdAt": date,
+ "updatedAt": date,
+ "nb_suivis": 0,
+ "id_artiste": artist,
+ }
+ try:
+ insert_reponse = """
+ INSERT INTO `artiste`(`nb_suivis`,`id_artiste`, `createdAt`, `updatedAt` )
+ VALUES (%(nb_suivis)s,%(id_artiste)s,%(createdAt)s,%(updatedAt)s)
+ """
+ cursor.execute(insert_reponse, data_to_insert)
+ except Exception as err:
+ print(f"Artist already exist")
+ for artist in artists:
+ for id_utilisateur in ids:
+ if(random.random() > 0.85): continue
+ data_to_insert = {
+ "createdAt": date,
+ "updatedAt": date,
+ "id_utilisateur": id_utilisateur,
+ "id_artiste": artist,
+ }
+ insert_reponse = """
+ INSERT INTO `follow`(`id_utilisateur`,`id_artiste`, `createdAt`, `updatedAt` )
+ VALUES (%(id_utilisateur)s,%(id_artiste)s,%(createdAt)s,%(updatedAt)s)
+ """
+ cursor.execute(insert_reponse, data_to_insert)
+def putReponse(cursor,reponse,ids, review_ids):
+ reponse_ids = []
+ for i in range(len(review_ids)):
+ rid = None
+ for y in range(random.randint(0,5)):
+ date = faker.Faker().date_between(start_date='-1y', end_date='today')
+ data_to_insert = {
+ "description": random.choice(reponse),
+ "createdAt": date,
+ "updatedAt": date,
+ "id_utilisateur": random.choice(ids),
+ "id_review": review_ids[i],
+ "id_reponse": rid,
+ }
+ insert_reponse = """
+ INSERT INTO `commentaire`(`description`, `id_review`,`id_utilisateur`,`id_reponse`, `createdAt`, `updatedAt` )
+ VALUES (%(description)s,%(id_review)s,%(id_utilisateur)s,%(id_reponse)s,%(createdAt)s,%(updatedAt)s)
+ """
+ cursor.execute(insert_reponse, data_to_insert)
+ rid = cursor.lastrowid
+ reponse_ids.append(rid)
+ return reponse_ids
+def putReview(cursor,review, ids,track_ids):
+ review_ids = []
+ for i in range(len(ids)):
+ if(random.random() < 0.5):
+ date = faker.Faker().date_between(start_date='-1y', end_date='today')
+ data_to_insert = {
+ "description": random.choice(review),
+ "note": random.randint(0,5),
+ "createdAt": date,
+ "updatedAt": date,
+ "id_utilisateur": ids[i],
+ "id_oeuvre": random.choice(track_ids),
+ "id_type_review": 1
+ }
+ insert_review = """
+ INSERT INTO `review`(`description`, `note`, `createdAt`, `updatedAt`, `id_utilisateur`,`id_oeuvre`,`id_type_review`)
+ VALUES (%(description)s,%(note)s,%(createdAt)s,%(updatedAt)s,%(id_utilisateur)s,%(id_oeuvre)s,%(id_type_review)s)
+ """
+ cursor.execute(insert_review, data_to_insert)
+ # Récupérer l'ID de l'utilisateur créé
+ review_ids.append(cursor.lastrowid)
+ return review_ids
+def putLikesReview(cursor,ids,review_ids):
+ for i in range(len(review_ids)):
+ for y in range(len(ids)):
+ if(random.random() <0.2): continue
+ date = faker.Faker().date_between(start_date='-1y', end_date='today')
+ data_to_insert = {
+ "createdAt": date,
+ "updatedAt": date,
+ "id_utilisateur": ids[y],
+ "id_review": review_ids[i],
+
+ }
+ insert_query = """
+ INSERT INTO `like_review`(`id_utilisateur`, `id_review`, `createdAt`, `updatedAt`)
+ VALUES (%(id_utilisateur)s,%(id_review)s,%(createdAt)s,%(updatedAt)s)
+ """
+ cursor.execute(insert_query, data_to_insert)
+
+
+def putLikesReponse(cursor,ids,reponse_ids):
+ for i in range(len(reponse_ids)):
+ for y in range(len(ids)):
+ if(random.random() <0.2): continue
+ date = faker.Faker().date_between(start_date='-1y', end_date='today')
+ data_to_insert = {
+ "createdAt": date,
+ "updatedAt": date,
+ "id_utilisateur": ids[y],
+ "id_com": reponse_ids[i],
+
+ }
+ insert_query = """
+ INSERT INTO `like_commentaire`(`id_utilisateur`, `id_com`, `createdAt`, `updatedAt`)
+ VALUES (%(id_utilisateur)s,%(id_com)s,%(createdAt)s,%(updatedAt)s)
+ """
+ cursor.execute(insert_query, data_to_insert)
+
+def insert_relation(cursor,ids):
+ validation = {}
+ date = faker.Faker().date_between(start_date='-1y', end_date='today')
+ for i in range(len(ids)):
+ for y in range(len(ids)):
+ if(i == y or random.random() < 0.4):
+ continue
+ en_attente = 1
+ if(f"key-{y}-{i}" in validation):
+ en_attente = 0
+ validation[f"key-{y}-{i}"][0]['en_attente'] = 0
+ data_to_insert = {
+ "en_attente": en_attente,
+ "id_utilisateur": ids[i],
+ "amiIdUtilisateur": ids[y],
+ "createdAt": date,
+ "updatedAt": date,
+ }
+ insert_query = """
+ INSERT INTO amis
+ (en_attente,id_utilisateur, amiIdUtilisateur, createdAt,updatedAt)
+ VALUES (%(en_attente)s, %(id_utilisateur)s, %(amiIdUtilisateur)s, %(createdAt)s, %(updatedAt)s)
+ """
+ validation[f"key-{i}-{y}"] = [data_to_insert,insert_query]
+ # Récupérer l'ID de l'utilisateur créé
+
+ for value in validation.values():
+ try:
+ cursor.execute(value[1], value[0])
+ except Exception as err:
+ print(f"Erreur lors de l'insertion dans la base de données : {err}")
+
+def obtenir_prenoms_aleatoires(nombre):
+ # Remplacez l'URL de l'API par celle que vous souhaitez utiliser
+ api_url = f"https://opendata.paris.fr/api/explore/v2.1/catalog/datasets/liste_des_prenoms/records?select=prenoms&limit=100&offset={random.randint(0,10000)}"
+ try:
+ # Effectuer la requête à l'API
+ reponse = requests.get(api_url)
+ # Vérifier si la requête a réussi (code de statut 200)
+ if reponse.status_code == 200:
+ # Extraire les prénoms de la réponse JSON
+ prenoms_api = reponse.json()
+ # Sélectionner un échantillon aléatoire de prénoms
+ sample = [x["prenoms"] for x in prenoms_api["results"]]
+ prenoms_aleatoires = random.sample(sample, min(nombre, len(sample)))
+ return prenoms_aleatoires
+ else:
+ print(f"Erreur lors de la requête à l'API. Code de statut : {reponse.status_code}")
+ except Exception as e:
+ print(f"Erreur lors de la requête à l'API : {e}")
+
+n = 50
+biographies = [
+ "Explorateur du monde en 150 caractères. Passionné de voyages, de cultures et de moments uniques. #LifeExplorer",
+ "Artiste en herbe, créant des chefs-d'œuvre avec chaque coup de pinceau. #ArtLife #PassionCréative",
+ "Architecte de la vie, construisant des rêves un jour à la fois. #DreamBuilder #LifeArchitect",
+ "Mordu de fitness, repoussant mes limites chaque jour. #FitLife #ChallengeAccepted",
+ "Globe-trotteur intrépide, capturant des souvenirs partout où je vais. #Wanderlust #AdventureSeeker",
+ "Amateur de mots, jonglant avec les lettres pour créer des univers magiques. #WordWizard #Storyteller",
+ "Explorateur culinaire, découvrant de nouveaux plaisirs gustatifs. #FoodieAdventures #TasteExplorer",
+ "Passionné de tech, naviguant à travers le monde numérique. #TechEnthusiast #DigitalNomad",
+ "Danseur de la vie, rythmant chaque moment avec grâce et énergie. #DanceLife #JoyfulRhythms",
+ "Aventurier des étoiles, explorant l'univers avec curiosité. #Stargazer #CosmicExplorer",
+ "Éco-warrior, défenseur de notre planète. #GreenLiving #EarthDefender",
+ "Exploratrice du bien-être, cultivant l'harmonie intérieure. #WellnessJourney #MindfulLiving",
+ "Ingénieur du bonheur, construisant des ponts vers la joie. #HappinessEngineer #PositiveVibesOnly",
+ "Mélomane moderne, explorant les notes du passé et du présent. #MusicExplorer #HarmonySeeker",
+ "Maître des codes, tissant des histoires à travers le langage binaire. #CodeArtisan #DigitalStoryteller"
+]
+
+# Afficher la liste complète
+reviews_musicales = [
+ "Une symphonie transcendante qui emporte l'auditeur dans un voyage émotionnel profond. #ChefDOeuvre #MusiqueClassique",
+ "Des rythmes hypnotiques qui font vibrer l'âme, une expérience musicale inoubliable. #GrooveIntense #MusiqueDuMonde",
+ "Des paroles poignantes qui capturent l'esprit de toute une génération. #TextesProfonds #ChansonEngagée",
+ "Un mélange parfait de mélodies envoûtantes et de beats entraînants. #VibesPositives #PopPerfection",
+ "Une performance vocale à couper le souffle, une véritable démonstration de talent. #VoixExceptionnelle #SoulfulSounds",
+ "Des accords de guitare envoûtants qui créent une atmosphère intime et captivante. #AcousticMagic #FolkVibes",
+ "Innovation sonore à son apogée, repoussant les limites de l'expérimentation musicale. #AvantGarde #SoundExploration",
+ "Un album qui transcende les genres, une fusion audacieuse de styles musicaux. #GenreBlending #Eclectique",
+ "Des harmonies célestes qui transportent l'auditeur dans un état de béatitude. #HarmonieParfaite #AmbianceCéleste",
+ "Des beats percutants et des paroles incisives, un manifeste musical de rébellion. #RythmesEngagés #RebelAttitude",
+ "Une expérience auditive immersive, chaque morceau est une aventure sensorielle unique. #SonEn3D #AudioExpérience",
+ "Un crescendo émotionnel qui éveille les passions les plus profondes. #ÉmotionsIntenses #CrescendoEmotionnel",
+ "Des arrangements subtils qui capturent l'essence de la nostalgie d'une époque révolue. #VintageVibes #NostalgieMusicale",
+ "Des beats entraînants qui font vibrer le corps, une invitation à la piste de danse. #RythmesContagieux #DanceFloorAnthems",
+ "Un tour de force musical qui transcende les générations, une œuvre intemporelle. #MusiqueÉternelle #ClassicForever"
+]
+
+reponses_reviews = [
+ "Merci pour cette superbe critique! Tellement d'accord sur l'impact émotionnel de cette symphonie. #PartageonsNosÉmotions",
+ "Ces rythmes m'ont aussi transporté! On devrait tous explorer davantage la diversité musicale du monde. #MusiqueUniverselle",
+ "Les paroles de cette chanson m'ont vraiment touché. La musique peut être une force puissante pour le changement. #PowerOfLyrics",
+ "D'accord à 100%! Les vibes positives de cet album sont exactement ce dont on a besoin. #SpreadJoy #MusicLover",
+ "Sa voix est une merveille! Tellement d'émotion derrière chaque note. #VoixInoubliable #MusicalSoulmate",
+ "J'aime ces accords de guitare! Ils créent une ambiance si chaleureuse et authentique. #AcousticMagic #FolkVibesForever",
+ "Absolument, l'innovation sonore est si rafraîchissante. On a besoin de plus d'expérimentation dans la musique! #PushingBoundaries",
+ "Je suis totalement d'accord avec cette analyse! La fusion de genres est une véritable prouesse artistique. #EclectiqueForever",
+ "Ces harmonies sont vraiment transcendantes. Chaque écoute est une expérience méditative. #MusiqueMystique #AudioPhile",
+ "Les paroles engagées résonnent vraiment avec moi. La musique peut être un moyen puissant de transmettre un message. #MusicActivism",
+ "Tu as décrit parfaitement cette expérience immersive! On se sent transporté à chaque écoute. #AudioVoyage #SonicDreams",
+ "Le crescendo émotionnel est époustouflant! On ressent chaque montée et descente de l'émotion. #CrescendoMagique #EmotionalJourney",
+ "Tellement vrai! Les arrangements subtils ajoutent une couche de nostalgie et d'authenticité. #VintageVibes #TimelessTunes",
+ "J'ai dansé toute la nuit sur ces beats entraînants! La musique a le pouvoir de rassembler les gens sur la piste de danse. #MusicUnity",
+ "L'œuvre intemporelle transcende vraiment les générations. Un chef-d'œuvre qui restera gravé dans l'histoire musicale. #ClassicMasterpiece",
+ "Merci pour cette critique passionnée! Il est génial de voir tant d'enthousiasme pour la musique. #MusicEnthusiast #KeepListening"
+]
+
+track_ids = [
+ "0wJoRiX5K5BxlqZTolB2LD",
+ "2AxCeJ6PSsBYiTckM0HLY7",
+ "0NWPxcsf5vdjdiFUI8NgkP",
+ "1Eolhana7nKHYpcYpdVcT5",
+ "1ntxpzIUbSsizvuAy6lTYY",
+ "23MrkN7g6Q5U7GLIxNHN1B",
+ "0auKlivXpm76wR63mMJ3pR",
+ "5uDpwSGjljhIgDB1ZYdp9c",
+ "5LI7PoHEolR8plrf3I16sq",
+ "5H6Jp0syB5yEPk7SWYdlmk",
+]
+
+artists = [
+ '6mEQK9m2krja6X1cfsAjfl',
+ '7yeFMUrYTY5cAZx0GKXnti',
+ '7Ln80lUS6He07XvHI8qqHH',
+ '13ubrt8QOOCPljQ2FL1Kca',
+ '711MCceyCBcFnzjGY4Q7Un',
+ '3QVolfxko2UyCOtexhVTli'
+]
+pseudo = obtenir_prenoms_aleatoires(n)
+conn = mysql.connector.connect(
+ host="localhost",
+ user="root",
+ password="root",
+ database="spotify",
+ port=3306
+)
+
+print("-------------INSERT USERS----------------------")
+password = "$2b$10$feqJS.qjWmoYovS805Mmhu.7VjOncR68em0Bu4LSxS/4tDSP8HWK2"
+ids = []
+cursor = conn.cursor()
+for data in pseudo:
+ id = insertUser(cursor,data,password,random.choice(biographies))
+ if(id is not None):
+ ids.append(id)
+
+print("-------------INSERT FOLLOW----------------------")
+insert_follow(cursor,ids,artists)
+print("-------------INSERT RELATIONS----------------------")
+insert_relation(cursor,ids)
+
+print("-------------INSERT REVIEWS----------------------")
+review_ids = putReview(cursor,reviews_musicales,ids,track_ids)
+putLikesReview(cursor,ids,review_ids)
+print("-------------INSERT COMMENT----------------------")
+reponse_ids = putReponse(cursor, reponses_reviews,ids,review_ids)
+putLikesReponse(cursor,ids,reponse_ids)
+conn.commit()
+
diff --git a/test/integration/artist.test.js b/test/integration/artist.test.js
new file mode 100644
index 0000000..f022f71
--- /dev/null
+++ b/test/integration/artist.test.js
@@ -0,0 +1,123 @@
+'use strict';
+const Hapi = require('@hapi/hapi');
+const strategy = require("../../lib/infrastructure/config/strategy");
+const Jwt = require("@hapi/jwt");
+const jwt = require('jsonwebtoken');
+
+require('dotenv').config()
+let server
+const mockReviewRepository = {}
+const mockAccesTokenManager = {}
+const mockUserRepository = {}
+const mockSpotifyRepository = {}
+const mockFollowRepository = {}
+
+mockAccesTokenManager.generate = ((test) =>{return ''})
+const mockToken = jwt.sign({
+ sub: 'my-sub',
+ value: 1,
+ aud: 'urn:audience:test',
+ iss: 'urn:issuer:test',
+ expiresIn: '365d'
+}, process.env.SECRET_ENCODER)
+
+describe('artist route', () => {
+
+ beforeEach(async () => {
+
+ server = Hapi.server({
+ port: process.env.PORT || 3000
+ });
+ server.app.serviceLocator = {
+ reviewRepository: mockReviewRepository,
+ accessTokenManager: mockAccesTokenManager,
+ userRepository: mockUserRepository,
+ spotifyRepository: mockSpotifyRepository,
+ followRepository: mockFollowRepository,
+ }
+ server.register(Jwt)
+ server.auth.strategy('jwt', 'jwt', strategy({userRepository: mockUserRepository}));
+ await server.register([
+ require('../../lib/interfaces/routes/artist'),
+ ]);
+ });
+
+ afterEach(async () => {
+ jest.clearAllMocks();
+ await server.stop();
+ });
+ const {
+ mockUser,
+ mockArtist,
+ mockUserPrivate,
+ mockAlbumRaw,
+ mockLikedReview,
+ mockCommentedReview,
+ mockOeuvreReviewSpotify,
+ } = require('./fixture/artist/getArtistFixture')
+ describe("GET review route", ()=>{
+
+ it("should return status code 200", async () => {
+
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((id) => mockUser)
+ mockFollowRepository.getFollowersCount = jest.fn((artistId) => 100)
+ mockFollowRepository.getFriendsFollowing = jest.fn((artistId,userId,limit) => [mockUserPrivate])
+ mockFollowRepository.getFriendsFollowingCount = jest.fn((artistId,userId) => 1)
+ mockSpotifyRepository.getSpotifyArtist = jest.fn((artistId) => mockArtist)
+ mockSpotifyRepository.getSpotifyArtistSongs = jest.fn((artistId,filter,limit) => mockAlbumRaw)
+ mockReviewRepository.getOeuvreRating = jest.fn((id) => 1)
+ mockReviewRepository.getReviewCount = jest.fn((id) => 2)
+ mockReviewRepository.getOeuvreReviews = jest.fn().mockReturnValueOnce([mockLikedReview]).mockReturnValueOnce([mockCommentedReview])
+ mockreviewRepository.doesUserLikes = jest.fn().mockReturnValue(true)
+ mockFollowRepository.doesFollows = jest.fn().mockReturnValue(true)
+ mockSpotifyRepository.getOeuvre = jest.fn().mockReturnValue(mockOeuvreReviewSpotify)
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/artist/test`,
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res1.statusCode).toBe(200);
+
+ })
+ it("should return status code 401", async () => {
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((id) => null)
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/artist/test`,
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res1.statusCode).toBe(401);
+
+ })
+ it("should return status code 400", async () => {
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((id) => mockUser)
+ mockSpotifyRepository.getSpotifyArtist = jest.fn((artistId) => {
+ return {
+ error: {
+ status: 400,
+ message: "message",
+ }
+ }
+ })
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/artist/test`,
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res1.statusCode).toBe(400);
+
+ })
+
+ })
+
+
+});
diff --git a/test/integration/fixture/artist/getArtistFixture.js b/test/integration/fixture/artist/getArtistFixture.js
new file mode 100644
index 0000000..abf8c1b
--- /dev/null
+++ b/test/integration/fixture/artist/getArtistFixture.js
@@ -0,0 +1,217 @@
+const mockArtist = {
+ external_urls: {
+ spotify: "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",
+ },
+ genres: ["french hip hop", "old school rap francais", "rap conscient"],
+ id: "4FpJcNgOvIpSBeJgRg3OfN",
+ images: [
+ {
+ height: 640,
+ url: "https://i.scdn.co/image/ab6761610000e5eb32086a424e6f1e499e347cde",
+ width: 640,
+ },
+ ],
+ name: "Orelsan",
+ popularity: 64,
+ type: "artist",
+};
+const mockAlbumRaw = {
+ href: "https://api.spotify.com/v1/artists/4FpJcNgOvIpSBeJgRg3OfN/albums?include_groups=album,single&offset=0&limit=10",
+ items: [
+ {
+ album_group: "album",
+ album_type: "album",
+ artists: [
+ {
+ external_urls: {
+ spotify: "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",
+ },
+ id: "4FpJcNgOvIpSBeJgRg3OfN",
+ name: "Orelsan",
+ type: "artist",
+ },
+ ],
+ external_urls: {
+ spotify: "https://open.spotify.com/album/68YP0pEgwhnfRqQAzu71gP",
+ },
+ id: "68YP0pEgwhnfRqQAzu71gP",
+ images: [
+ {
+ height: 640,
+ url: "https://i.scdn.co/image/ab67616d0000b2732724364cd86bb791926b6cc8",
+ width: 640,
+ },
+ ],
+ name: "Civilisation Edition Ultime",
+ release_date: "2022-10-28",
+ total_tracks: 25,
+ type: "album",
+ },
+ ],
+};
+const mockUser = {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false,
+};
+
+const mockUserPrivate = {
+ pseudo: "John Doe2",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ id_utilisateur: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: true,
+};
+const actualDate = new Date();
+
+const mockLikedReview = {
+ id_review: 25,
+ id_oeuvre: "68YP0pEgwhnfRqQAzu71gP",
+ countlikes: 32,
+ countComment: 0,
+ description:
+ "Innovation sonore à son apogée, repoussant les limites de l'expérimentation musicale. #AvantGarde #SoundExploration",
+ note: 5,
+ createdAt: "2024-01-03T00:00:00.000Z",
+ updated_at: "2024-01-03T00:00:00.000Z",
+ type: "album",
+ utilisateur: {
+ id_utilisateur: 54,
+ pseudo: "Constance",
+ email: "Constance.Constance@gmail.com",
+ auth_with_spotify: false,
+ alias: "Constance",
+ photo: "https://ozgrozer.github.io/100k-faces/0/6/006026.jpg",
+ photo_temporaire: null,
+ token: null,
+ refresh_token: null,
+ reset_token: null,
+ password: "$2b$10$feqJS.qjWmoYovS805Mmhu.7VjOncR68em0Bu4LSxS/4tDSP8HWK2",
+ id_role: 1,
+ ban_until: null,
+ confirmed: true,
+ confirm_token: null,
+ auth_with_spotify: false,
+ is_private: true,
+ type: "user",
+ },
+};
+
+const mockCommentedReview = {
+ id_review: 25,
+ id_oeuvre: "68YP0pEgwhnfRqQAzu71gP",
+ countlikes: 32,
+ countComment: 0,
+ description:
+ "Innovation sonore à son apogée, repoussant les limites de l'expérimentation musicale. #AvantGarde #SoundExploration",
+ note: 5,
+ createdAt: "2024-01-03T00:00:00.000Z",
+ updated_at: "2024-01-03T00:00:00.000Z",
+ type: "album",
+ utilisateur: {
+ id_utilisateur: 54,
+ pseudo: "Constance",
+ email: "Constance.Constance@gmail.com",
+ auth_with_spotify: false,
+ alias: "Constance",
+ photo: "https://ozgrozer.github.io/100k-faces/0/6/006026.jpg",
+ photo_temporaire: null,
+ token: null,
+ refresh_token: null,
+ reset_token: null,
+ password: "$2b$10$feqJS.qjWmoYovS805Mmhu.7VjOncR68em0Bu4LSxS/4tDSP8HWK2",
+ id_role: 1,
+ ban_until: null,
+ confirmed: true,
+ confirm_token: null,
+ auth_with_spotify: false,
+ is_private: true,
+ type: "user",
+ },
+};
+
+const mockOeuvreReviewSpotify = {
+ album_type: "album",
+ artists: [
+ {
+ external_urls: {
+ spotify: "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",
+ },
+ id: "4FpJcNgOvIpSBeJgRg3OfN",
+ name: "Orelsan",
+ type: "artist",
+ },
+ ],
+
+ external_urls: {
+ spotify: "https://open.spotify.com/album/68YP0pEgwhnfRqQAzu71gP",
+ },
+ genres: [],
+ id: "68YP0pEgwhnfRqQAzu71gP",
+ images: [
+ {
+ height: 640,
+ url: "https://i.scdn.co/image/ab67616d0000b2732724364cd86bb791926b6cc8",
+ width: 640,
+ },
+ ],
+ name: "Civilisation Edition Ultime",
+ popularity: 60,
+ release_date: "2022-10-28",
+ total_tracks: 1,
+ tracks: {
+ href: "https://api.spotify.com/v1/albums/68YP0pEgwhnfRqQAzu71gP/tracks?offset=0&limit=50",
+ items: [
+ {
+ artists: [
+ {
+ external_urls: {
+ spotify: "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",
+ },
+ href: "https://api.spotify.com/v1/artists/4FpJcNgOvIpSBeJgRg3OfN",
+ id: "4FpJcNgOvIpSBeJgRg3OfN",
+ name: "Orelsan",
+ type: "artist",
+ uri: "spotify:artist:4FpJcNgOvIpSBeJgRg3OfN",
+ },
+ ],
+
+ disc_number: 1,
+ duration_ms: 161732,
+ external_urls: {
+ spotify: "https://open.spotify.com/track/7b3YQboXo3kau9YVUyx3r4",
+ },
+ id: "7b3YQboXo3kau9YVUyx3r4",
+ name: "CP_001_ Intro Civilisation Perdue",
+ preview_url:
+ "https://p.scdn.co/mp3-preview/b7f3ef4f7ee54bcba700a821952539b7e4e21d2f?cid=24b7c8fbb7d146edbce14e1743cea479",
+ track_number: 1,
+ type: "track",
+ },
+ ],
+ total: 25,
+ },
+ type: "album",
+};
+
+module.exports = {
+ mockUser,
+ mockArtist,
+ mockUserPrivate,
+ mockAlbumRaw,
+ mockLikedReview,
+ mockCommentedReview,
+ mockOeuvreReviewSpotify,
+};
diff --git a/test/integration/fixture/imageTest.jpg b/test/integration/fixture/imageTest.jpg
new file mode 100644
index 0000000..a723e03
Binary files /dev/null and b/test/integration/fixture/imageTest.jpg differ
diff --git a/test/integration/fixture/review/getOeuvreReviewFixture.js b/test/integration/fixture/review/getOeuvreReviewFixture.js
new file mode 100644
index 0000000..ae20643
--- /dev/null
+++ b/test/integration/fixture/review/getOeuvreReviewFixture.js
@@ -0,0 +1,60 @@
+const mockArtist = {
+ id: "32kWZXLpwGm5Y2B0lKb6Ii",
+ name: "Bob Marley",
+ images: [{
+ height: 640,
+ url: "https://i.scdn.co/image/ab67616d0000b273c9adfbd773852e286faed040",
+ width: 640
+ }],
+ external_urls: {spotify: "https://open.spotify.com/artist/32kWZXLpwGm5Y2B0lKb6Ii"},
+ popularity: 79,
+ genres: ["Reggae", "Roots"]
+}
+const mockUser = {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+}
+const mockPublicUser = {
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_utilisateur: 1,
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+}
+
+const actualDate = new Date()
+const rawReview = {
+ id_review: 1,
+ id_oeuvre: 1,
+ countlikes: 2,
+ countComment: 4,
+ description: "C'est top",
+ note: 5,
+ createdAt: actualDate,
+ updated_at: actualDate,
+ type: 'artist',
+ utilisateur: mockUser
+}
+
+
+
+
+
+
+module.exports = {
+ mockArtist,
+ rawReview,
+}
\ No newline at end of file
diff --git a/test/integration/fixture/review/getOeuvreReviewsFixture.js b/test/integration/fixture/review/getOeuvreReviewsFixture.js
new file mode 100644
index 0000000..16508d7
--- /dev/null
+++ b/test/integration/fixture/review/getOeuvreReviewsFixture.js
@@ -0,0 +1,47 @@
+const mockArtist = {
+ id: "32kWZXLpwGm5Y2B0lKb6Ii",
+ name: "Bob Marley",
+ images: [{
+ height: 640,
+ url: "https://i.scdn.co/image/ab67616d0000b273c9adfbd773852e286faed040",
+ width: 640
+ }],
+ external_urls: {spotify: "https://open.spotify.com/artist/32kWZXLpwGm5Y2B0lKb6Ii"},
+ popularity: 79,
+ genres: ["Reggae", "Roots"]
+}
+const mockUser = {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+}
+
+
+const actualDate = new Date()
+const rawReview = {
+ id_review: 1,
+ id_oeuvre: 1,
+ countlike: 2,
+ countComment: 4,
+ description: "C'est top",
+ note: 5,
+ createdAt: actualDate,
+ updated_at: actualDate,
+ type: 'artist',
+ utilisateur: mockUser
+}
+
+
+
+
+module.exports = {
+ mockArtist,
+ rawReview,
+}
\ No newline at end of file
diff --git a/test/integration/fixture/review/getReviewFixture.js b/test/integration/fixture/review/getReviewFixture.js
new file mode 100644
index 0000000..b933e54
--- /dev/null
+++ b/test/integration/fixture/review/getReviewFixture.js
@@ -0,0 +1,55 @@
+const mockArtist = {
+ id: "32kWZXLpwGm5Y2B0lKb6Ii",
+ name: "Bob Marley",
+ images: [{
+ height: 640,
+ url: "https://i.scdn.co/image/ab67616d0000b273c9adfbd773852e286faed040",
+ width: 640
+ }],
+ external_urls: {spotify: "https://open.spotify.com/artist/32kWZXLpwGm5Y2B0lKb6Ii"},
+ popularity: 79,
+ genres: ["Reggae", "Roots"]
+}
+const mockUser = {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+
+}
+
+const actualDate = new Date()
+const rawReview = {
+ id_review: 1,
+ id_oeuvre: 1,
+ countlike: 2,
+ countComment: 4,
+ description: "C'est top",
+ note: 5,
+ createdAt: actualDate,
+ updatedAt: actualDate,
+ type: 'artist',
+ utilisateur: mockUser
+}
+
+const mockComments = [
+ {
+ id: 298,
+ description: 'test4',
+ utilisateur: mockUser
+ }
+]
+
+
+
+module.exports = {
+ rawReview,
+ mockArtist,
+ mockComments,
+}
\ No newline at end of file
diff --git a/test/integration/fixture/review/getReviewLikesFixture.js b/test/integration/fixture/review/getReviewLikesFixture.js
new file mode 100644
index 0000000..c5289b5
--- /dev/null
+++ b/test/integration/fixture/review/getReviewLikesFixture.js
@@ -0,0 +1,28 @@
+const mockUser = {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+
+}
+const mockPublicUser = {
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+}
+module.exports = {
+ mockUser,
+ mockPublicUser
+}
\ No newline at end of file
diff --git a/test/integration/friend.test.js b/test/integration/friend.test.js
new file mode 100644
index 0000000..51d19f8
--- /dev/null
+++ b/test/integration/friend.test.js
@@ -0,0 +1,398 @@
+'use strict';
+const Hapi = require('@hapi/hapi');
+const Friend = require("../../lib/domain/model/Friend")
+const User = require("../../lib/domain/model/User")
+const strategy = require("../../lib/infrastructure/config/strategy");
+const Jwt = require("@hapi/jwt");
+const jwt = require('jsonwebtoken');
+require('dotenv').config()
+let server
+const mockUserRepository = {}
+const mockFriendRepository = {}
+const mockMailRepository = {}
+const mockAccesTokenManager = {}
+
+mockAccesTokenManager.generate = ((test) =>{return ''})
+const mockToken = jwt.sign({
+ sub: 'my-sub',
+ value: 1,
+ aud: 'urn:audience:test',
+ iss: 'urn:issuer:test',
+ expiresIn: '365d'
+}, process.env.SECRET_ENCODER)
+
+describe('friend route', () => {
+
+ beforeEach(async () => {
+
+ server = Hapi.server({
+ port: process.env.PORT || 3000
+ });
+ server.app.serviceLocator = {
+ userRepository: mockUserRepository,
+ friendRepository: mockFriendRepository,
+ mailRepository: mockMailRepository,
+ accessTokenManager:mockAccesTokenManager
+ }
+ server.register(Jwt)
+ server.auth.strategy('jwt', 'jwt', strategy({userRepository: mockUserRepository}));
+ await server.register([
+ require('../../lib/interfaces/routes/friends'),
+ ]);
+ });
+
+ afterEach(async () => {
+ jest.clearAllMocks();
+ await server.stop();
+ });
+
+ describe("/amis/follow", ()=>{
+ afterEach(()=>{
+ jest.clearAllMocks();
+ })
+ beforeEach(()=>{
+ mockUserRepository.getByUser = jest.fn((id)=> {
+ return new User({pseudo:"test", id_utilisateur:id, email: "test@gmail.com", alias: "testt", is_private: true})
+ })
+ mockFriendRepository.persist = jest.fn((test) => {
+ return test
+ })
+ mockMailRepository.send = jest.fn(option => null)
+ mockAccesTokenManager.decode = jest.fn((token)=> {return {value: 1}})
+
+ })
+ it('should respond code 200 with token user', async () => {
+ const res = await server.inject({
+ method: 'POST',
+ url: '/amis/follow',
+ payload: {
+ amiIdUtilisateur: 2
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+
+ expect(res.statusCode).toBe(200);
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockFriendRepository.persist).toHaveBeenCalledTimes(1)
+ expect(mockMailRepository.send).toHaveBeenCalledTimes(1)
+ });
+ it('should respond code 400 with invalid id friend', async () => {
+ mockUserRepository.getByUser = jest.fn((id)=> {
+ if(id > 0) return new User({pseudo:"test", id_utilisateur:id, email: "test@gmail.com", alias: "testt", is_private: false})
+ return null
+ })
+ const res = await server.inject({
+ method: 'POST',
+ url: '/amis/follow',
+ payload: {
+ amiIdUtilisateur: -2
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res.statusCode).toBe(400);
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockFriendRepository.persist).toHaveBeenCalledTimes(0)
+ expect(mockMailRepository.send).toHaveBeenCalledTimes(0)
+ });
+ it('should respond code 403 with already existing frindship', async () => {
+ mockUserRepository.getByUser = jest.fn((id)=> {
+ return new User({pseudo:"test", id_utilisateur:id, email: "test@gmail.com", alias: "testt", is_private: true})
+ })
+ mockFriendRepository.persist = jest.fn((f)=> null)
+ const res = await server.inject({
+ method: 'POST',
+ url: '/amis/follow',
+ payload: {
+ amiIdUtilisateur: 2
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res.statusCode).toBe(403);
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockFriendRepository.persist).toHaveBeenCalledTimes(1)
+ expect(mockMailRepository.send).toHaveBeenCalledTimes(0)
+ });
+
+ })
+
+ describe("/amis/unfollow", ()=>{
+ afterEach(()=>{
+ jest.clearAllMocks();
+ })
+ beforeEach(()=>{
+ mockUserRepository.getByUser = jest.fn((id)=> {
+ return new User({pseudo:"test", id_utilisateur:id, email: "test@gmail.com", alias: "testt", is_private: true})
+ })
+ mockFriendRepository.removeFriendById = jest.fn((id, id_ami) => {
+ return new Friend({id_utilisateur:id, amiIdUtilisateur:id_ami, en_attente:true})
+ })
+ mockAccesTokenManager.decode = jest.fn((token)=> {return {value: 1}})
+
+ })
+
+ it('should respond code 200 with token user', async () => {
+
+ const res = await server.inject({
+ method: 'POST',
+ url: '/amis/unfollow',
+ payload: {
+ amiIdUtilisateur: 2
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+
+ expect(res.statusCode).toBe(200);
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1);
+ expect(mockFriendRepository.removeFriendById).toHaveBeenCalledTimes(1)
+ });
+ it('should respond code 400 with invalid id friend', async () => {
+ mockUserRepository.getByUser= jest.fn((id)=> {
+ if(id > 0) return new User({pseudo:"test", id_utilisateur:id, email: "test@gmail.com", alias: "testt", is_private: false})
+ return null
+ })
+ const res = await server.inject({
+ method: 'POST',
+ url: '/amis/unfollow',
+ payload: {
+ amiIdUtilisateur: -2
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res.statusCode).toBe(400);
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockFriendRepository.removeFriendById).toHaveBeenCalledTimes(0)
+ });
+ it('should respond code 403 with frindship doesn\'t exist', async () => {
+ mockFriendRepository.removeFriendById = jest.fn((f)=> null)
+ const res = await server.inject({
+ method: 'POST',
+ url: '/amis/unfollow',
+ payload: {
+ amiIdUtilisateur: 3
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res.statusCode).toBe(403);
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockFriendRepository.removeFriendById).toHaveBeenCalledTimes(1)
+ });
+
+ })
+
+ describe("/amis/accept", ()=>{
+ afterEach(()=>{
+ jest.clearAllMocks();
+ })
+ beforeEach(()=>{
+ mockUserRepository.getByUser = jest.fn((id)=> {
+ return new User({pseudo:"test", id_utilisateur:id, email: "test@gmail.com", alias: "testt", is_private: true})
+ })
+ mockFriendRepository.accept = jest.fn((id, id_ami) => {
+ return new Friend({id_utilisateur:id, amiIdUtilisateur:id_ami, en_attente:true})
+ })
+ mockAccesTokenManager.decode = jest.fn((token)=> {return {value: 1}})
+ })
+
+ it('should respond code 200 with token user and friend', async () => {
+ const res = await server.inject({
+ method: 'POST',
+ url: '/amis/accept',
+ payload: {
+ amiIdUtilisateur: 2
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+
+ expect(res.statusCode).toBe(200);
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockFriendRepository.accept).toHaveBeenCalledTimes(1)
+ });
+ it('should respond code 400 with invalid id friend', async () => {
+ mockUserRepository.getByUser= jest.fn((id)=> {
+ if(id > 0) return new User({pseudo:"test", id_utilisateur:id, email: "test@gmail.com", alias: "testt", is_private: false})
+ return null
+ })
+ const res = await server.inject({
+ method: 'POST',
+ url: '/amis/accept',
+ payload: {
+ amiIdUtilisateur: -2
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res.statusCode).toBe(400);
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockFriendRepository.accept).toHaveBeenCalledTimes(0)
+ });
+ it('should respond code 403 with frindship doesn\'t exist', async () => {
+ mockFriendRepository.accept = jest.fn((f)=> null)
+ const res = await server.inject({
+ method: 'POST',
+ url: '/amis/accept',
+ payload: {
+ amiIdUtilisateur: 2
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res.statusCode).toBe(403);
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockFriendRepository.accept).toHaveBeenCalledTimes(1)
+ });
+
+ })
+
+ describe("/amis/profil", ()=>{
+ afterEach(()=>{
+ jest.clearAllMocks();
+ })
+ beforeEach(()=>{
+ mockUserRepository.getByUser = jest.fn((id)=> {
+ return new User({pseudo:"test", id_utilisateur:id, email: "test@gmail.com", alias: "testt", is_private: true})
+ })
+ mockFriendRepository.getById = jest.fn((id, id_ami) => {
+ return new Friend({amiIdUtilisateur:id_ami, id_utilisateur:id, en_attente: false})
+ })
+ mockAccesTokenManager.decode = jest.fn((token)=> {return {value: 1}})
+ });
+
+ it('should respond code 400 with invalid id friend', async () => {
+ mockUserRepository.getByUser= jest.fn((id)=> {
+ if(id > 0) return new User({pseudo:"test", id_utilisateur:id, email: "test@gmail.com", alias: "testt", is_private: false})
+ return null
+ })
+ const res = await server.inject({
+ method: 'POST',
+ url: '/amis/profil',
+ payload: {
+ amiIdUtilisateur: -1
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res.statusCode).toBe(400);
+ expect(mockUserRepository.getByUser).toHaveBeenCalledTimes(3)
+ expect(mockFriendRepository.getById).toHaveBeenCalledTimes(0)
+ });
+ it('should respond code 200', async () => {
+ mockUserRepository.getByUser= jest.fn((id)=> {
+ if(id > 0) return new User({pseudo:"test", id_utilisateur:id, email: "test@gmail.com", alias: "testt", is_private: false})
+ return null
+ })
+ const res = await server.inject({
+ method: 'POST',
+ url: '/amis/profil',
+ payload: {
+ amiIdUtilisateur: 3
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res.statusCode).toBe(200);
+ expect(mockUserRepository.getByUser).toHaveBeenCalledTimes(3)
+ expect(mockFriendRepository.getById).toHaveBeenCalledTimes(1)
+ });
+ it('should respond code 403 with frindship doesn\'t exist', async () => {
+ mockFriendRepository.getById = jest.fn((id, id_ami)=> {
+ return null
+ })
+ const res = await server.inject({
+ method: 'POST',
+ url: '/amis/profil',
+ payload: {
+ amiIdUtilisateur: 3
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res.statusCode).toBe(403);
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockUserRepository.getByUser).toHaveBeenCalledTimes(3)
+ expect(mockFriendRepository.getById).toHaveBeenCalledTimes(1)
+ });
+
+ })
+
+ describe("/amis/list", ()=>{
+ afterEach(()=>{
+ jest.clearAllMocks();
+ })
+
+ mockUserRepository.getByUser = jest.fn((id)=> {
+ return new User({pseudo:"test", id_utilisateur:id, email: "test@gmail.com", alias: "testt", is_private: true})
+ })
+ mockFriendRepository.getListFriendsById = jest.fn((id) => {
+ return [
+ new User({pseudo:"test", id_utilisateur:1, email: "test@gmail.com", alias: "testt", is_private: true}),
+ new User({pseudo:"test2", id_utilisateur:2, email: "test2@gmail.com", alias: "testt2", is_private: false})
+ ]
+ })
+ mockAccesTokenManager.decode = jest.fn((token)=> {return {value: 1}})
+
+ it('should respond code 200 with token user', async () => {
+ const res = await server.inject({
+ method: 'GET',
+ url: '/amis/list',
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+
+ expect(res.statusCode).toBe(200);
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockFriendRepository.getListFriendsById).toHaveBeenCalledTimes(1)
+ });
+ })
+
+ describe("/amis/request", ()=>{
+ afterEach(()=>{
+ jest.clearAllMocks();
+ })
+ beforeEach( async ()=>{
+ mockUserRepository.getByUser = jest.fn((id)=> {
+ return new User({pseudo:"test", id_utilisateur:id, email: "test@gmail.com", alias: "testt", is_private: true})
+ })
+ mockFriendRepository.getRequestFriendsById = jest.fn((id) => {
+ return [
+ new User({pseudo:"test", id_utilisateur:2, email: "test@gmail.com", alias: "testt", is_private: true}),
+ new User({pseudo:"test2", id_utilisateur:3, email: "test2@gmail.com", alias: "testt2", is_private: true})
+ ]
+ })
+ mockAccesTokenManager.decode = jest.fn((token)=> {return {value: 1}})
+ })
+
+ it('should respond code 200 with token user', async () => {
+ const res = await server.inject({
+ method: 'GET',
+ url: '/amis/request',
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+
+ expect(res.statusCode).toBe(200);
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockFriendRepository.getRequestFriendsById).toHaveBeenCalledTimes(1)
+ });
+ })
+});
diff --git a/test/integration/oeuvre.test.js b/test/integration/oeuvre.test.js
new file mode 100644
index 0000000..5db7eae
--- /dev/null
+++ b/test/integration/oeuvre.test.js
@@ -0,0 +1,129 @@
+'use strict';
+const Hapi = require('@hapi/hapi');
+const strategy = require("../../lib/infrastructure/config/strategy");
+const Jwt = require("@hapi/jwt");
+const jwt = require('jsonwebtoken');
+
+require('dotenv').config()
+let server
+const mockUserRepository = {}
+const mockLikeOeuvreRepository = {}
+const mockAccessTokenManager = {}
+const mockSpotifyRepository = {}
+
+mockAccessTokenManager.generate = ((test) =>{return ''})
+const mockToken = jwt.sign({
+ sub: 'my-sub',
+ value: 1,
+ aud: 'urn:audience:test',
+ iss: 'urn:issuer:test',
+ expiresIn: '365d'
+}, process.env.SECRET_ENCODER)
+
+describe('artist route', () => {
+
+ beforeEach(async () => {
+
+ server = Hapi.server({
+ port: process.env.PORT || 3000
+ });
+ server.app.serviceLocator = {
+ userRepository: mockUserRepository,
+ likeOeuvreRepository: mockLikeOeuvreRepository,
+ accessTokenManager: mockAccessTokenManager,
+ spotifyRepository: mockSpotifyRepository
+ }
+ server.register(Jwt)
+ server.auth.strategy('jwt', 'jwt', strategy({userRepository: mockUserRepository}));
+ await server.register([
+ require('../../lib/interfaces/routes/oeuvre'),
+ ]);
+ });
+
+ afterEach(async () => {
+ jest.clearAllMocks();
+ await server.stop();
+ });
+ describe("POST oeuvre/{type}/{id}/like route", ()=>{
+ const mockUser = {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+ }
+ const mockArtist = {
+ external_urls: { spotify: 'https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN' },
+ genres: [ 'french hip hop', 'old school rap francais', 'rap conscient' ],
+ id: '4FpJcNgOvIpSBeJgRg3OfN',
+ images: [
+ {
+ height: 640,
+ url: 'https://i.scdn.co/image/ab6761610000e5eb32086a424e6f1e499e347cde',
+ width: 640
+ },
+ ],
+ name: 'Orelsan',
+ popularity: 64,
+ type: 'artist',
+ }
+ const errror = {
+ error: {
+ status: 400,
+ message: "message",
+ }
+ }
+ it("should return status code 200", async () => {
+
+ mockAccessTokenManager.decode = jest.fn(()=>{return {value:1}})
+ mockUserRepository.getByUser = jest.fn().mockReturnValue(mockUser)
+ mockSpotifyRepository.getOeuvre = jest.fn().mockReturnValue(mockArtist)
+ mockLikeOeuvreRepository.doesUserLike = jest.fn().mockReturnValue(false)
+ mockLikeOeuvreRepository.like = jest.fn()
+ const res1 = await server.inject({
+ method: 'POST',
+ url: `/oeuvre/artist/4FpJcNgOvIpSBeJgRg3OfN/like`,
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res1.statusCode).toBe(200);
+
+ })
+ it("should return status code 401", async () => {
+ mockAccessTokenManager.decode = jest.fn(()=>{return {value:1}})
+ mockUserRepository.getByUser = jest.fn().mockReturnValue(null)
+ const res1 = await server.inject({
+ method: 'POST',
+ url: `/oeuvre/artist/4FpJcNgOvIpSBeJgRg3OfN/like`,
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res1.statusCode).toBe(401);
+
+ })
+ it("should return status code 400", async () => {
+ mockAccessTokenManager.decode = jest.fn(()=>{return {value:1}})
+ mockUserRepository.getByUser = jest.fn().mockReturnValue(mockUser)
+ mockSpotifyRepository.getOeuvre = jest.fn().mockReturnValue(errror)
+ const res1 = await server.inject({
+ method: 'POST',
+ url: `/oeuvre/artist/4FpJcNgOvIpSBeJgRg3OfN/like`,
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res1.statusCode).toBe(400);
+
+ })
+
+ })
+
+
+});
diff --git a/test/integration/review.test.js b/test/integration/review.test.js
new file mode 100644
index 0000000..52232cc
--- /dev/null
+++ b/test/integration/review.test.js
@@ -0,0 +1,533 @@
+'use strict';
+const Hapi = require('@hapi/hapi');
+const strategy = require("../../lib/infrastructure/config/strategy");
+const Jwt = require("@hapi/jwt");
+const jwt = require('jsonwebtoken');
+
+require('dotenv').config()
+let server
+const mockReviewRepository = {}
+const mockFriendRepository = {}
+const mockAccesTokenManager = {}
+const mockSpotifyRepository = {}
+const mockUserRepository = {}
+const mockCommentRepository = {}
+
+mockAccesTokenManager.generate = ((test) =>{return ''})
+const mockToken = jwt.sign({
+ sub: 'my-sub',
+ value: 1,
+ aud: 'urn:audience:test',
+ iss: 'urn:issuer:test',
+ expiresIn: '365d'
+}, process.env.SECRET_ENCODER)
+
+describe('review route', () => {
+
+ beforeEach(async () => {
+
+ server = Hapi.server({
+ port: process.env.PORT || 3000
+ });
+ server.app.serviceLocator = {
+ reviewRepository: mockReviewRepository,
+ friendRepository: mockFriendRepository,
+ accessTokenManager: mockAccesTokenManager,
+ spotifyRepository: mockSpotifyRepository,
+ userRepository: mockUserRepository,
+ commentRepository: mockCommentRepository
+ }
+ server.register(Jwt)
+ server.auth.strategy('jwt', 'jwt', strategy({userRepository: mockUserRepository}));
+ await server.register([
+ require('../../lib/interfaces/routes/review'),
+ ]);
+ });
+
+ afterEach(async () => {
+ jest.clearAllMocks();
+ await server.stop();
+ });
+ const {
+ mockArtist,
+ rawReview,
+ mockComments
+ } = require("./fixture/review/getReviewFixture")
+ describe("GET review route", ()=>{
+
+ it("should return status code 200", async () => {
+ mockCommentRepository.getReviewComments = jest.fn().mockReturnValue(mockComments)
+ mockReviewRepository.getById = jest.fn((id) => rawReview)
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => mockArtist)
+ mockCommentRepository.getReviewComments = jest.fn().mockReturnValue(mockComments)
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/review/1?page=1&pageSize=10&orderByLike=true`,
+ });
+ expect(res1.statusCode).toBe(200);
+
+ })
+ it("should return status code 404", async () => {
+ mockReviewRepository.getById = jest.fn((id) => null)
+ mockCommentRepository.getReviewComments = jest.fn().mockReturnValue(mockComments)
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/review/1?page=1&pageSize=10&orderByLike=true`,
+ });
+ expect(res1.statusCode).toBe(404);
+
+ })
+ it("should return status code 403", async () => {
+ const mockReview = {
+ utilisateur: {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ is_private: true
+ }
+ }
+ mockCommentRepository.getReviewComments = jest.fn().mockReturnValue(mockComments)
+ mockReviewRepository.getById = jest.fn((id) => mockReview)
+ mockFriendRepository.areFriends = jest.fn((id, id_ami) => false)
+ mockAccesTokenManager.decode = jest.fn((token) => {return {value: 1}})
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/review/1?page=1&pageSize=10&orderByLike=true`,
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+
+ });
+ expect(res1.statusCode).toBe(403);
+
+ })
+ it("should return status code 400", async () => {
+ mockCommentRepository.getReviewComments = jest.fn().mockReturnValue(mockComments)
+ mockReviewRepository.getById = jest.fn((id) => rawReview)
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => {
+ return {
+ error: {
+ status: 400,
+ message: "message",
+ }
+ }
+ })
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/review/1?page=1&pageSize=10&orderByLike=true`,
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res1.statusCode).toBe(400);
+
+ })
+ })
+ describe("GET reviews route", ()=>{
+ it("should return status code 200", async ()=>{
+
+ mockReviewRepository.getReviews = jest.fn((page,pageSize,orderByLike, isPrivate,userToken) => [rawReview])
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => mockArtist)
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/reviews?page=1&pageSize=10&orderByLike=true`,
+
+ });
+ expect(res1.statusCode).toBe(200);
+ })
+
+ it("should return status code 200 with user login", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((token) => {return {value: 1}})
+ mockReviewRepository.getReviews = jest.fn((page,pageSize,orderByLike, isPrivate,userToken) => [rawReview])
+ mockreviewRepository.doesUserLikes = jest.fn((id_utilisateur,reviewId) => false)
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => mockArtist)
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/reviews?page=1&pageSize=10&orderByLike=true`,
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res1.statusCode).toBe(200);
+ })
+ })
+
+ describe("DELETE review route", ()=>{
+ it("should return status code 200", async ()=>{
+ mockReviewRepository.delete = jest.fn((id) => true)
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((id) => {
+ return {
+ id_utilisateur: 1
+ }
+ })
+ const res1 = await server.inject({
+ method: 'DELETE',
+ url: `/review`,
+ payload: {
+ idReview: 'idReview'
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+
+ });
+ expect(res1.statusCode).toBe(200);
+ })
+
+ it("should return status code 401 no header", async ()=>{
+ mockReviewRepository.delete = jest.fn((id) => true)
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((id) => {
+ return {
+ id_utilisateur: 1
+ }
+ })
+ const res1 = await server.inject({
+ method: 'DELETE',
+ url: `/review`,
+ payload: {
+ idReview: 'idReview'
+ },
+ });
+ expect(res1.statusCode).toBe(401);
+ })
+
+ it("should return status code 401 bad auth token", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((id) => null)
+ const res1 = await server.inject({
+ method: 'DELETE',
+ url: `/review`,
+ payload: {
+ idReview: 'idReview'
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res1.statusCode).toBe(401);
+ })
+ it("should return status code 401 not post owner", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((id) => {
+ return {
+ id_utilisateur: 1
+ }
+ })
+ mockReviewRepository.delete = jest.fn((id) => false)
+ const res1 = await server.inject({
+ method: 'DELETE',
+ url: `/review`,
+ payload: {
+ idReview: 'idReview'
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res1.statusCode).toBe(403);
+ })
+ })
+
+ describe("GET reviewLikes route", ()=>{
+ const {
+ mockUser,
+ mockPublicUser
+ } = require("./fixture/review/getReviewLikesFixture")
+ it("should return status code 404", async ()=>{
+ mockReviewRepository.getById = jest.fn((id) => null)
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/review/1/likes?page=1&pageSize=10`,
+ // headers: {
+ // Authorization: `Bearer ${mockToken}`
+ // }
+ });
+ expect(res1.statusCode).toBe(404)
+ })
+ it("should return status code 403", async ()=>{
+ const mockReview = {
+ utilisateur: {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ is_private: true
+ }
+ }
+ mockReviewRepository.getById = jest.fn((id) => mockReview)
+ mockAccesTokenManager.decode = jest.fn((token) => {return {value: 1}})
+ mockFriendRepository.areFriends = jest.fn((id, id_ami) => false)
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/review/1/likes?page=1&pageSize=10`,
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res1.statusCode).toBe(403)
+ })
+ it("should return status code 200", async ()=>{
+ const mockReview = {
+ utilisateur: {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ is_private: false
+ }
+ }
+ mockReviewRepository.getById = jest.fn((id) => mockReview)
+ mockReviewRepository.getLikes = jest.fn((id) => [mockUser])
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/review/1/likes?page=1&pageSize=10`,
+ });
+ expect(res1.statusCode).toBe(200)
+ })
+ })
+
+ describe("GET userReviews route", ()=>{
+ it("should return status code 200", async ()=>{
+ mockUserRepository.getByEmailOrPseudo = jest.fn((pseudo,email) => {
+ return {
+ id_utilisateur: 1,
+ is_private: false
+ }
+ })
+ mockReviewRepository.getReviewByUserId = jest.fn((id_utilisateur,page,pageSize,orderByLike) => [rawReview])
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => mockArtist)
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/reviews/user/{id}?page=1&pageSize=10&orderByLike=true`,
+ });
+ expect(res1.statusCode).toBe(200);
+ })
+
+ it("should return status code 403", async ()=>{
+ mockUserRepository.getByEmailOrPseudo = jest.fn((pseudo,email) => {
+ return {
+ id_utilisateur: 1,
+ is_private: true
+ }
+ })
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/reviews/user/{id}?page=1&pageSize=10&orderByLike=true`,
+ });
+ expect(res1.statusCode).toBe(403);
+ })
+
+ it("should return status code 404", async ()=>{
+ mockUserRepository.getByEmailOrPseudo = jest.fn().mockReturnValue(null)
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/reviews/user/{id}?page=1&pageSize=10&orderByLike=true`,
+ });
+ expect(res1.statusCode).toBe(404);
+ })
+ })
+
+ describe("GET reviewLike route",()=>{
+ it("should return status code 200", async ()=>{
+ const mockReview = {
+ utilisateur: {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ is_private: false
+ }
+ }
+ const mockUser = {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+
+ }
+ mockReviewRepository.getById = jest.fn((id) => mockReview)
+ mockReviewRepository.getLikes = jest.fn((id) => [mockUser])
+
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/review/1/likes?page=1&pageSize=10`,
+ });
+ expect(res1.statusCode).toBe(200);
+ })
+
+ it("should return status code 403", async ()=>{
+
+ const mockReview = {
+ utilisateur: {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ is_private: true
+ }
+ }
+ mockReviewRepository.getById = jest.fn((id) => mockReview)
+ mockAccesTokenManager.decode = jest.fn((token) => {return {value: 1}})
+ mockFriendRepository.areFriends = jest.fn((id, id_ami) => false)
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/review/1/likes?page=1&pageSize=10`,
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res1.statusCode).toBe(403);
+
+ })
+ it("should return status code 404", async ()=>{
+
+ mockReviewRepository.getById = jest.fn((id) => null)
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/review/1/likes?page=1&pageSize=10`,
+ });
+ expect(res1.statusCode).toBe(404);
+
+ })
+ })
+
+ describe("PUT review route",()=>{
+ it("should return status code 200", async ()=>{
+ mockUserRepository.getByUser = jest.fn((userToken) => {
+ return {
+ id_utilisateur: 1
+ }
+ })
+ mockReviewRepository.getByUserAndId = jest.fn((idOeuvre, id_utilisateur) => null)
+ mockReviewRepository.getTypeReviewID = jest.fn((type) => 1)
+ mockReviewRepository.persist = jest.fn((reviewRaw) => rawReview)
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => mockArtist)
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ const res1 = await server.inject({
+ method: 'PUT',
+ url: `/review`,
+ payload: {
+ idOeuvre: 'idOeuvre',
+ description: 'description',
+ note: 5,
+ type: 'artist'
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res1.statusCode).toBe(200);
+ })
+
+ it("should return status code 400", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((userToken) => {
+ return {
+ id_utilisateur: 1
+ }
+ })
+ mockReviewRepository.getByUserAndId = jest.fn((idOeuvre, id_utilisateur) => null)
+ mockReviewRepository.getTypeReviewID = jest.fn((type) => 1)
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => {
+ return {
+ error: {
+ status: 400,
+ message: 'error'
+ }
+ }
+ })
+ const res1 = await server.inject({
+ method: 'PUT',
+ url: `/review`,
+ payload: {
+ idOeuvre: 'idOeuvre',
+ description: 'description',
+ note: 5,
+ type: 'artist'
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res1.statusCode).toBe(400);
+ })
+ it("should return status code 401", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((userToken) => null)
+ const res1 = await server.inject({
+ method: 'PUT',
+ url: `/review`,
+ payload: {
+ idOeuvre: 'idOeuvre',
+ description: 'description',
+ note: 5,
+ type: 'artist'
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res1.statusCode).toBe(401);
+ })
+ it("should return status code 403", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((userToken) => {
+ return {
+ id_utilisateur: 1
+ }
+ })
+ mockReviewRepository.getByUserAndId = jest.fn((idOeuvre, id_utilisateur) => {
+ return {
+ id_review: 1
+ }
+ })
+ const res1 = await server.inject({
+ method: 'PUT',
+ url: `/review`,
+ payload: {
+ idOeuvre: 'idOeuvre',
+ description: 'description',
+ note: 5,
+ type: 'artist'
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`
+ }
+ });
+ expect(res1.statusCode).toBe(403);
+ })
+ })
+
+ describe("GET oeuvreReviews",()=>{
+ const {
+ mockArtist,
+ rawReview,
+ } = require("./fixture/review/getOeuvreReviewFixture.js")
+ it("should return status code 200", async ()=>{
+ mockReviewRepository.getOeuvreReviews = jest.fn((id_utilisateur,page,pageSize,orderByLike) => [rawReview])
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => mockArtist)
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/reviews/oeuvre/{id}?page=1&pageSize=10&orderByLike=true`,
+ });
+ expect(res1.statusCode).toBe(200);
+ })
+
+ it("should return status code 400", async ()=>{
+ mockReviewRepository.getOeuvreReviews = jest.fn((id_utilisateur,page,pageSize,orderByLike) => [rawReview])
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => {
+ return {
+ error: {
+ status: 400,
+ message: "message",
+ }
+ }
+ })
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/reviews/oeuvre/{id}?page=1&pageSize=10&orderByLike=true`,
+ });
+ expect(res1.statusCode).toBe(400);
+ })
+
+ })
+});
diff --git a/test/integration/spotify.test.js b/test/integration/spotify.test.js
index 53394cf..c77aa1c 100644
--- a/test/integration/spotify.test.js
+++ b/test/integration/spotify.test.js
@@ -2,11 +2,22 @@
const Hapi = require('@hapi/hapi');
const User = require("../../lib/domain/model/User")
const bcrypt = require("bcrypt");
+const {
+ rawTrackWithServeralArtists,
+} = require("../unit/interfaces/serializers/fixtures/trackFixture");
+const {
+ albumRawOneArtist,
+} = require("../unit/interfaces/serializers/fixtures/albumFixture");
+
+const getTrack = require("../../lib/application/use_cases/spotify/getTrack");
+const catchError = require("../unit/application/usecase/utils/catchError");
let server
const mockUserRepository = {}
const mockSpotifyRepository = {}
mockUserRepository.getUsersByPseudo = jest.fn((pseudo) =>{return []})
mockSpotifyRepository.getSpotifySearchList = jest.fn((query, filter, limitSize) =>{return {}})
+mockSpotifyRepository.getSpotifyArtist = jest.fn((id) =>{return {}}) // mock la fct de repo
+mockSpotifyRepository.getSpotifyArtistSongs = jest.fn((id, filter, limit) =>{return {}})
describe('spotify route', () => {
@@ -29,22 +40,14 @@ describe('spotify route', () => {
it('should respond code 400 invalid query', async () => {
const res1 = await server.inject({
method: 'GET',
- url: `/spotify/search?query=${"a".repeat(51)}&spotify_filter=trddzack&allow_user=true&limit=10`,
+ url: `/spotify/search?query=${"a".repeat(51)}&spotify_filter=trddzack&limit=10`,
});
expect(res1.statusCode).toBe(400);
});
it('should respond code 400 invalid spotify_filter', async () => {
const res1 = await server.inject({
method: 'GET',
- url: `/spotify/search?query=query&spotify_filter=trddzack&allow_user=true&limit=10`,
- });
-
- expect(res1.statusCode).toBe(400);
- });
- it('should respond code 400 invalid allow_user', async () => {
- const res1 = await server.inject({
- method: 'GET',
- url: `/spotify/search?query=query&spotify_filter=track&allow_user=dsd&limit=10`,
+ url: `/spotify/search?query=query&spotify_filter=trddzack&limit=10`,
});
expect(res1.statusCode).toBe(400);
@@ -52,13 +55,13 @@ describe('spotify route', () => {
it('should respond code 400 invalid limit', async () => {
const res1 = await server.inject({
method: 'GET',
- url: `/spotify/search?query=query&spotify_filter=track&allow_user=true&limit=cez`,
+ url: `/spotify/search?query=query&spotify_filter=track&limit=cez`,
});
expect(res1.statusCode).toBe(400);
});
it('should respond code 200', async () => {
- const allowedValues = ["track","artist","album"]
+ const allowedValues = ["track","artist","album","user"]
const getAllSubset = (array) =>{
const n = array.length;
const allSubsets = [];
@@ -79,11 +82,147 @@ describe('spotify route', () => {
for(let i =1; i{
+ it('should respond code 200', async () => {
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/spotify/Searchfilters`,
+ });
+ expect(res1.statusCode).toBe(200);
+ });
+ })
+ describe("/spotify/FetchArtist", ()=>{
+ it('should respond code 400 invalid query/id', async () => {
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/spotify/fetchArtist?query=`,
+ });
+ expect(res1.statusCode).toBe(400);
+ });
+ it('should respond code 200', async () => {
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/spotify/fetchArtist?query=query`,
+ });
+ expect(res1.statusCode).toBe(200);
+ });
+ it('should respond code 400 invalidID', async () => {
+ mockSpotifyRepository.getSpotifyArtist = jest.fn((id) =>{
+ throw new Error('test error')
+ })
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/spotify/fetchArtist?query=query`,
+ });
+ expect(res1.statusCode).toBe(400);
+ });
+ })
+ describe('/spotify/track', () => {
+ it("should invalid return code 400", async ()=>{
+ mockSpotifyRepository.getSpotifyTracks = jest.fn((id) =>{
+ return {error : {status: 400, message: "msg"}}
+ })
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/spotify/track?id=29092`,
+ });
+ expect(res1.statusCode).toBe(400);
+ })
+ it("should invalid return code 200", async ()=>{
+ mockSpotifyRepository.getSpotifyTracks = jest.fn((id) =>{
+ return rawTrackWithServeralArtists
+ })
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/spotify/track?id=29092`,
+ });
+ expect(res1.statusCode).toBe(200);
+ })
+ });
+ describe('/spotify/album', () => {
+ it("should invalid return code 400", async ()=>{
+ mockSpotifyRepository.getSpotifyAlbums = jest.fn((id) =>{
+ return {error : {status: 400, message: "msg"}}
+ })
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/spotify/album?id=29092`,
+ });
+ expect(res1.statusCode).toBe(400);
+ })
+ it("should invalid return code 200", async ()=>{
+ mockSpotifyRepository.getSpotifyAlbums = jest.fn((id) =>{
+ return albumRawOneArtist
+ })
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/spotify/album?id=29092`,
+ });
+ expect(res1.statusCode).toBe(200);
+ })
+
+ });
+
+
+ describe("/spotify/FetchArtistSongs", ()=>{
+
+ it('should respond code 200', async () => {
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/spotify/fetchArtistSongs?id=azerty1234`, // juste id, filter, limit optional
+ });
+ expect(res1.statusCode).toBe(200);
+ });
+
+ it('should respond code 200', async () => {
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/spotify/fetchArtistSongs?id=azerty1234&limit=10`, // juste id et limit
+ });
+ expect(res1.statusCode).toBe(200);
+ });
+
+ it('should respond code 200', async () => {
+ const res1 = await server.inject({
+ method: 'GET',
+ url: '/spotify/fetchArtistSongs?id=azerty1234&filter= album , compilation , appears_on ' // id et filtre avec espaces
+ });
+ expect(res1.statusCode).toBe(200);
+ });
+
+ it('should respond code 400', async () => {
+ const res1 = await server.inject({
+ method: 'GET',
+ url: '/spotify/fetchArtistSongs?id=azerty1234&filter= albu , compilation , appears_on ' // mauvaise orthographe sur un filtre
+ });
+ expect(res1.statusCode).toBe(400);
+ });
+
+
+ it('should respond code 400 invalid id', async () => {
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/spotify/fetchArtistSongs?id=`,
+ });
+ expect(res1.statusCode).toBe(400);
+ });
+
+ it('should respond code 400 invalidID', async () => {
+ mockSpotifyRepository.getSpotifyArtistSongs = jest.fn((id) =>{
+ throw new Error('test error')
+ })
+ const res1 = await server.inject({
+ method: 'GET',
+ url: `/spotify/fetchArtistSongs?id=1234`,
+ });
+ expect(res1.statusCode).toBe(400);
+ });
+ })
});
diff --git a/test/integration/users.test.js b/test/integration/users.test.js
index 9d25b15..5f66178 100644
--- a/test/integration/users.test.js
+++ b/test/integration/users.test.js
@@ -1,297 +1,971 @@
-'use strict';
-const Hapi = require('@hapi/hapi');
-const User = require("../../lib/domain/model/User")
+"use strict";
+const Hapi = require("@hapi/hapi");
+const User = require("../../lib/domain/model/User");
const bcrypt = require("bcrypt");
-let server
-const mockUserRepository = {}
-const mockAccesTokenManager = {}
-mockUserRepository.getByEmailOrPseudo = jest.fn((email,pseudo) => {
- return null
-})
-mockUserRepository.persist = jest.fn((test) =>{
- return test
-})
-
-mockAccesTokenManager.generate = ((test) =>{return ''})
-describe('user route', () => {
-
- beforeEach(async () => {
- server = Hapi.server({
- port: process.env.PORT || 3000
- });
- await server.register([
- require('../../lib/interfaces/routes/users'),
- ]);
- server.app.serviceLocator = {
- userRepository: mockUserRepository,
- accessTokenManager:mockAccesTokenManager
- }
- });
-
- afterEach(async () => {
- await server.stop();
- });
- describe("/users/signup", ()=>{
- it('should respond code 200', async () => {
- const res = await server.inject({
- method: 'POST',
- url: '/users/signup',
- payload: {
- email: "tesddesqt@gmaiL.com",
- pseudo: "testsss",
- alias: "testsss",
- password: "pdazdazassworrdddd",
- spotifyToken: "tokeeeeen",
- bio: "dzada"
- }
- });
- expect(res.statusCode).toBe(200);
- });
-
-
- it('should respond code 403', async () => {
- mockUserRepository.getByEmailOrPseudo = jest.fn((email,pseudo) => {
- return {}
- })
- const res = await server.inject({
- method: 'POST',
- url: '/users/signup',
- payload: {
- email: "tesddesqt@gmaiL.com",
- pseudo: "testsss",
- alias: "testsss",
- password: "pdazdazassworrdddd",
- spotifyToken: "tokeeeeen",
- bio: "dzada"
- }
- });
- expect(res.statusCode).toBe(403);
- });
-
- it('should respond code 400 with invalid email', async () => {
- const res = await server.inject({
- method: 'POST',
- url: '/users/signup',
- payload: {
- email: "te",
- pseudo: "testsss",
- alias: "testsss",
- password: "pdazdazassworrdddd",
- spotifyToken: "tokeeeeen",
- bio: "dzada"
- }
- });
- expect(res.statusCode).toBe(400);
- expect(JSON.parse(res.payload).validation.keys).toBe("email")
- });
-
- it('should respond code 400 with invalid pseudo', async () => {
- const res1 = await server.inject({
- method: 'POST',
- url: '/users/signup',
- payload: {
- email: "tesddesqt@gmaiL.com",
- pseudo: "test@sss",
- alias: "testsss",
- password: "pdazdazassworrdddd",
- spotifyToken: "tokeeeeen",
- bio: "dzada"
- }
- });
- const res2 = await server.inject({
- method: 'POST',
- url: '/users/signup',
- payload: {
- email: "tesddesqt@gmaiL.com",
- pseudo: "te",
- alias: "testsss",
- password: "pdazdazassworrdddd",
- spotifyToken: "tokeeeeen",
- bio: "dzada"
- }
- });
- const res3 = await server.inject({
- method: 'POST',
- url: '/users/signup',
- payload: {
- email: "tesddesqt@gmaiL.com",
- pseudo: 'a'.repeat(16),
- alias: "testsss",
- password: "pdazdazassworrdddd",
- spotifyToken: "tokeeeeen",
- bio: "dzada"
- }
- });
- expect(res1.statusCode).toBe(400);
- expect(JSON.parse(res1.payload).validation.keys).toBe("pseudo")
- expect(res2.statusCode).toBe(400);
- expect(JSON.parse(res2.payload).validation.keys).toBe("pseudo")
- expect(res3.statusCode).toBe(400);
- expect(JSON.parse(res3.payload).validation.keys).toBe("pseudo")
-
- });
-
- it('should respond code 400 with invalid alias', async () => {
- const res1 = await server.inject({
- method: 'POST',
- url: '/users/signup',
- payload: {
- email: "tesddesqt@gmaiL.com",
- pseudo: "testsss",
- alias: "te",
- password: "pdazdazassworrdddd",
- spotifyToken: "tokeeeeen",
- bio: "dzada"
- }
- });
- const res2 = await server.inject({
- method: 'POST',
- url: '/users/signup',
- payload: {
- email: "tesddesqt@gmaiL.com",
- pseudo: "testsss",
- alias: 'a'.repeat(16),
- password: "pdazdazassworrdddd",
- spotifyToken: "tokeeeeen",
- bio: "dzada"
- }
- });
-
- expect(res1.statusCode).toBe(400);
- expect(JSON.parse(res1.payload).validation.keys).toBe("alias")
- expect(res2.statusCode).toBe(400);
- expect(JSON.parse(res2.payload).validation.keys).toBe("alias")
-
- });
-
- it('should respond code 400 with invalid password', async () => {
- const res1 = await server.inject({
- method: 'POST',
- url: '/users/signup',
- payload: {
- email: "tesddesqt@gmaiL.com",
- pseudo: "testsss",
- alias: "testsss",
- password: "aa",
- spotifyToken: "tokeeeeen",
- bio: "dzada"
- }
- });
- const res2 = await server.inject({
- method: 'POST',
- url: '/users/signup',
- payload: {
- email: "tesddesqt@gmaiL.com",
- pseudo: "testsss",
- alias: "testsss",
- password: "a".repeat(31),
- spotifyToken: "tokeeeeen",
- bio: "dzada"
- }
- });
-
- expect(res1.statusCode).toBe(400);
- expect(JSON.parse(res1.payload).validation.keys).toBe("password")
- expect(res2.statusCode).toBe(400);
- expect(JSON.parse(res2.payload).validation.keys).toBe("password")
- });
-
- it('should respond code 400 with invalid bio', async () => {
- const res1 = await server.inject({
- method: 'POST',
- url: '/users/signup',
- payload: {
- email: "tesddesqt@gmaiL.com",
- pseudo: "testsss",
- alias: "testsss",
- password: "aaaaaaaaaaa",
- spotifyToken: "tokeeeeen",
- bio: "a".repeat(1501)
- }
- });
-
-
- expect(res1.statusCode).toBe(400);
- expect(JSON.parse(res1.payload).validation.keys).toBe("bio")
- });
- })
- describe("/users/signin", ()=> {
-
-
- it('should respond code 200', async () => {
- const password = 'password'
- let fetchedUser = new User("id","pseudo","email","alias","bio",await bcrypt.hash(password,10),"token",1,1)
-
- mockUserRepository.getByIdent = jest.fn((ident) =>{
- return fetchedUser
- })
-
- const res = await server.inject({
- method: 'POST',
- url: '/users/signin',
- payload: {
- email:"tesddesqt@gmaiL.com",
- password: password,
- }}
- )
-
- expect(res.statusCode).toBe(200);
-
- })
- it('should respond code 401 bad password', async () => {
- const password = 'password'
- let fetchedUser = new User("id","pseudo","email","alias","bio",await bcrypt.hash(password,10),"token",1,1)
-
- mockUserRepository.getByIdent = jest.fn((ident) =>{
- return fetchedUser
- })
- const res = await server.inject({
- method: 'POST',
- url: '/users/signin',
- payload: {
- email:"tesddesqt@gmaiL.com",
- password: "aaaaadaaaaaa",
- }}
- )
- expect(res.statusCode).toBe(401);
- })
- it('should respond code 400 user not found', async () => {
- mockUserRepository.getByIdent = jest.fn((ident) =>{
- return null
- })
- const res = await server.inject({
- method: 'POST',
- url: '/users/signin',
- payload: {
- email:"fezfez",
- password: "aaaaadaaaaaa",
- }}
- )
- expect(res.statusCode).toBe(401);
- })
- it('should respond code 400 invalid email', async () => {
-
- const res = await server.inject({
- method: 'POST',
- url: '/users/signin',
- payload: {
- email:"fezfez",
- password: "a".repeat(31),
- }}
- )
- expect(res.statusCode).toBe(400);
- })
- it('should respond code 400 invalid password', async () => {
-
- const res = await server.inject({
- method: 'POST',
- url: '/users/signin',
- payload: {
- email:"a".repeat(41),
- password: "dzadzaa",
- }}
- )
- expect(res.statusCode).toBe(400);
- })
- })
+const strategy = require("../../lib/infrastructure/config/strategy");
+const Jwt = require("@hapi/jwt");
+const jwt = require("jsonwebtoken");
+const { type } = require("@hapi/joi/lib/extend.js");
+require("dotenv").config();
+let server;
+const mockUserRepository = {};
+const mockAccesTokenManager = {};
+const mockSpotifyRepository = {};
+const mockMailRepository = {};
+const mockDocumentRepository = {};
+const mockFollowRepository = {};
+const mockOeuvreFavRepository = {};
+const mockToken = jwt.sign(
+ {
+ sub: "my-sub", // needs to match definition above
+ value: 1, // this is a custom key I used, it could be named anything. Value should be a way to authenticate the user
+ aud: "urn:audience:test", // needs to match definition above
+ iss: "urn:issuer:test", // needs to match definition above,
+ expiresIn: "365d",
+ },
+ process.env.SECRET_ENCODER
+);
+
+mockAccesTokenManager.generate = (test) => {
+ return "";
+};
+describe("user route", () => {
+ beforeEach(async () => {
+ server = Hapi.server({
+ port: process.env.PORT || 3000,
+ });
+ server.app.serviceLocator = {
+ userRepository: mockUserRepository,
+ accessTokenManager: mockAccesTokenManager,
+ spotifyRepository: mockSpotifyRepository,
+ mailRepository: mockMailRepository,
+ documentRepository: mockDocumentRepository,
+ followRepository: mockFollowRepository,
+ oeuvreFavRepository: mockOeuvreFavRepository,
+ };
+ server.register(Jwt);
+ server.auth.strategy(
+ "jwt",
+ "jwt",
+ strategy({ userRepository: mockUserRepository })
+ );
+ await server.register([require("../../lib/interfaces/routes/users")]);
+ });
+
+ afterEach(async () => {
+ jest.clearAllMocks();
+ await server.stop();
+ });
+ describe("/users/createUser", () => {
+ afterEach(() => {
+ jest.clearAllMocks();
+ });
+ mockUserRepository.getByEmailOrPseudo = jest.fn((email, pseudo) => null);
+ mockUserRepository.persist = jest.fn((test) => {
+ return { id_utilisateur: 1 };
+ });
+ mockMailRepository.send = jest.fn((option) => null);
+ mockSpotifyRepository.getToken = jest.fn(() => {
+ return { access_token: 1, refresh_token: 1 };
+ });
+ it("should respond code 200 with email inscription", async () => {
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/createUser",
+ payload: {
+ email: "tesddesqt@gmaiL.com",
+ password: "somepassword",
+ },
+ });
+ expect(res.statusCode).toBe(200);
+ });
+
+ it("should respond code 403 with already existing email", async () => {
+ mockUserRepository.getByEmailOrPseudo = jest.fn(
+ (email, pseudo) => "something"
+ );
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/createUser",
+ payload: {
+ email: "tesddesqt@gmaiL.com",
+ password: "somepassword",
+ },
+ });
+ expect(res.statusCode).toBe(403);
+ });
+ });
+ describe("/users/confirmUser", () => {
+ afterEach(() => {
+ jest.clearAllMocks();
+ });
+
+ mockUserRepository.getByConfirmToken = jest.fn(() => {
+ return {
+ id_utilisateur: 1,
+ photo_temporaire: "path",
+ };
+ });
+ mockUserRepository.updateUser = jest.fn((user) => user);
+ mockUserRepository.persist = jest.fn((test) => {
+ return { id_utilisateur: 1 };
+ });
+ mockDocumentRepository.deleteFile = jest.fn(() => null);
+ it("should respond code 200 with confirmation and photo", async () => {
+ mockUserRepository.getByEmailOrPseudo = jest.fn((email, pseudo) => null);
+ const payload = {
+ pseudo: "testPseudo",
+ alias: "testAlias",
+ confirmToken: "token",
+ photo: "path",
+ bio: "bio",
+ };
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/confirmUser",
+ payload: payload,
+ });
+ expect(res.statusCode).toBe(200);
+ expect(mockDocumentRepository.deleteFile).toHaveBeenCalledTimes(1);
+ });
+ it("should respond code 200 with confirmation", async () => {
+ mockUserRepository.getByEmailOrPseudo = jest.fn((email, pseudo) => null);
+ const payload = {
+ pseudo: "testPseudo",
+ alias: "testAlias",
+ confirmToken: "token",
+ bio: "bio",
+ };
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/confirmUser",
+ payload: payload,
+ });
+ expect(res.statusCode).toBe(200);
+ expect(mockDocumentRepository.deleteFile).toHaveBeenCalledTimes(0);
+ });
+ it("should respond code 400", async () => {
+ mockUserRepository.getByEmailOrPseudo = jest.fn((email, pseudo) => null);
+ mockUserRepository.getByConfirmToken = jest.fn(() => null);
+ const payload = {
+ pseudo: "testPseudo",
+ alias: "testAlias",
+ confirmToken: "token",
+ bio: "bio",
+ };
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/confirmUser",
+ payload: payload,
+ });
+ expect(res.statusCode).toBe(400);
+ });
+ it("should respond code 403", async () => {
+ mockUserRepository.getByEmailOrPseudo = jest.fn(() => "someting");
+ const payload = {
+ pseudo: "testPseudo",
+ alias: "testAlias",
+ confirmToken: "token",
+ bio: "bio",
+ };
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/confirmUser",
+ payload: payload,
+ });
+ expect(res.statusCode).toBe(403);
+ });
+ });
+ describe("/users/signin", () => {
+ afterEach(() => {
+ jest.clearAllMocks();
+ });
+ mockUserRepository.getByUser = jest.fn((test) => {
+ return 1;
+ });
+ mockAccesTokenManager.generate = (test) => {
+ return "";
+ };
+ it("should respond code 200", async () => {
+ const password = "password";
+ const mockUserRaw = {
+ id_utilisateur: "id",
+ pseudo: "pseudo",
+ email: "email",
+ alias: "alias",
+ bio: "bio",
+ photo: "path/to/file",
+ photo_temporaire: "path/to/file",
+ password: await bcrypt.hash(password, 10),
+ token: "token",
+ id_role: 1,
+ ban_until: new Date("10-06-2003"),
+ };
+ const fetchedUser = new User(mockUserRaw);
+
+ mockUserRepository.getByIdent = jest.fn((ident) => {
+ return fetchedUser;
+ });
+
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/signin",
+ payload: {
+ email: "tesddesqt@gmaiL.com",
+ password: password,
+ },
+ });
+
+ expect(res.statusCode).toBe(200);
+ });
+ it("should respond code 401 bad password", async () => {
+ const password = "password";
+ const mockUserRaw = {
+ id_utilisateur: "id",
+ pseudo: "pseudo",
+ email: "email",
+ alias: "alias",
+ bio: "bio",
+ photo: "path/to/file",
+ photo_temporaire: "path/to/file",
+ password: await bcrypt.hash(password, 10),
+ token: "token",
+ id_role: 1,
+ ban_until: new Date("10-06-2003"),
+ };
+ const fetchedUser = new User(mockUserRaw);
+
+ mockUserRepository.getByIdent = jest.fn((ident) => {
+ return fetchedUser;
+ });
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/signin",
+ payload: {
+ email: "tesddesqt@gmaiL.com",
+ password: "aaaaadaaaaaa",
+ },
+ });
+ expect(res.statusCode).toBe(401);
+ });
+ it("should respond code 400 user not found", async () => {
+ mockUserRepository.getByIdent = jest.fn((ident) => {
+ return null;
+ });
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/signin",
+ payload: {
+ email: "fezfez",
+ password: "aaaaadaaaaaa",
+ },
+ });
+ expect(res.statusCode).toBe(401);
+ });
+ it("should respond code 400 invalid email", async () => {
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/signin",
+ payload: {
+ email: "fezfez",
+ password: "a".repeat(31),
+ },
+ });
+ expect(res.statusCode).toBe(400);
+ });
+ it("should respond code 400 invalid password", async () => {
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/signin",
+ payload: {
+ email: "a".repeat(41),
+ password: "dzadzaa",
+ },
+ });
+ expect(res.statusCode).toBe(400);
+ });
+ });
+ describe("/users/isUser", () => {
+ afterEach(() => {
+ jest.clearAllMocks();
+ });
+ it("should return true", async () => {
+ mockUserRepository.getByEmailOrPseudo = jest.fn(() => {
+ return { id_utilisateur: 1 };
+ });
+ const res = await server.inject({
+ method: "GET",
+ url: "/users/isUser?pseudo=test",
+ });
+ expect(res.statusCode).toBe(200);
+ expect(res.result.isUser).toBe(true);
+ });
+ it("should return false", async () => {
+ mockUserRepository.getByEmailOrPseudo = jest.fn(() => {
+ return null;
+ });
+ const res = await server.inject({
+ method: "GET",
+ url: "/users/isUser?pseudo=test",
+ });
+ expect(res.statusCode).toBe(200);
+ expect(res.result.isUser).toBe(false);
+ });
+ });
+ describe("/users/getUserByConfirmToken", () => {
+ it("should return valid code 200", async () => {
+ mockUserRepository.getByConfirmToken = jest.fn(() => {
+ return { id_utilisateur: 1 };
+ });
+ const res = await server.inject({
+ method: "GET",
+ url: "/users/getUserByConfirmToken?confirmToken=test",
+ });
+ expect(res.statusCode).toBe(200);
+ });
+ it("should return invalid code 403", async () => {
+ mockUserRepository.getByConfirmToken = jest.fn(() => {
+ return null;
+ });
+ const res = await server.inject({
+ method: "GET",
+ url: "/users/getUserByConfirmToken?confirmToken=test",
+ });
+ expect(res.statusCode).toBe(403);
+ });
+ });
+ describe("/users/sendResetEmail", () => {
+ it("should return valid code 200", async () => {
+ mockMailRepository.send = jest.fn(() => {});
+ mockUserRepository.getByEmailOrPseudo = jest.fn(() => {
+ return { reset_token: 1, confirmed: true };
+ });
+ mockUserRepository.updateUser = jest.fn(() => {});
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/sendResetEmail",
+ payload: {
+ email: "chanon.mael@gmail.com",
+ },
+ });
+ expect(res.statusCode).toBe(200);
+ expect(mockMailRepository.send).toHaveBeenCalledTimes(1);
+ });
+ it("should return valid code 200 even though the user is not confirmed", async () => {
+ mockMailRepository.send = jest.fn(() => {});
+ mockUserRepository.getByEmailOrPseudo = jest.fn(() => {
+ return { reset_token: 1, confirmed: false };
+ });
+ mockUserRepository.updateUser = jest.fn(() => {});
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/sendResetEmail",
+ payload: {
+ email: "chanon.mael@gmail.com",
+ },
+ });
+ expect(res.statusCode).toBe(200);
+ expect(mockMailRepository.send).toHaveBeenCalledTimes(0);
+ });
+ it("should return valid code 200 even though the user doesn't exists", async () => {
+ mockMailRepository.send = jest.fn(() => {});
+ mockUserRepository.getByEmailOrPseudo = jest.fn(() => {
+ return null;
+ });
+ mockUserRepository.updateUser = jest.fn(() => {});
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/sendResetEmail",
+ payload: {
+ email: "chanon.mael@gmail.com",
+ },
+ });
+ expect(res.statusCode).toBe(200);
+ expect(mockMailRepository.send).toHaveBeenCalledTimes(0);
+ });
+ });
+ describe("/users/resetPassword", () => {
+ it("should return valid code 200", async () => {
+ mockUserRepository.getByResetToken = jest.fn(() => {
+ return { id: 1 };
+ });
+ mockUserRepository.updateUser = jest.fn(() => {});
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/resetPassword",
+ payload: {
+ resetToken: "eztgergrehre",
+ password: "TestPassword",
+ },
+ });
+ expect(res.statusCode).toBe(200);
+ });
+ it("should return valid code 400 error on token", async () => {
+ mockUserRepository.getByResetToken = jest.fn(() => null);
+ mockUserRepository.updateUser = jest.fn(() => {});
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/resetPassword",
+ payload: {
+ resetToken: "eztgergrehre",
+ password: "TestPassword",
+ },
+ });
+ expect(res.statusCode).toBe(400);
+ });
+ });
+ describe("/users/follow", () => {
+ it("should return valid code 200", async () => {
+ mockAccesTokenManager.decode = jest.fn(() => {
+ return { id: 1 };
+ });
+ mockUserRepository.getByUser = jest.fn(() => "something");
+ mockSpotifyRepository.getSpotifyArtist = jest.fn(() => "something");
+ mockFollowRepository.doesFollows = jest.fn(() => true);
+ mockFollowRepository.follow = jest.fn(() => {});
+ mockFollowRepository.unfollow = jest.fn(() => {});
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/follow",
+ payload: {
+ artistId: "eztgergrehre",
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`,
+ },
+ });
+ expect(res.statusCode).toBe(200);
+ });
+ it("should return error code 401", async () => {
+ mockAccesTokenManager.decode = jest.fn(() => {
+ return { id: 1 };
+ });
+ mockUserRepository.getByUser = jest.fn(() => null);
+
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/follow",
+ payload: {
+ artistId: "eztgergrehre",
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`,
+ },
+ });
+ expect(res.statusCode).toBe(401);
+ });
+ it("should return return invalid code 415", async () => {
+ mockAccesTokenManager.decode = jest.fn(() => {
+ return { id: 1 };
+ });
+ mockUserRepository.getByUser = jest.fn(() => "something");
+ mockSpotifyRepository.getSpotifyArtist = jest.fn(() => {
+ return {
+ error: {
+ status: 415,
+ message: "message",
+ },
+ };
+ });
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/follow",
+ payload: {
+ artistId: "eztgergrehre",
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`,
+ },
+ });
+ expect(res.statusCode).toBe(415);
+ });
+ });
+ describe("AuthWithSpotifyTest", () => {
+ const mockSpotifyCode = "code";
+ const email = "some@mail";
+ const display_name = "name";
+ const access_token = "access_token";
+ const refresh_token = "refresh_token";
+ const images = [
+ "https://i.ytimg.com/vi/uLHdmBf1lvs/hq720.jpg?sqp=-oaymwEXCNAFEJQDSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLAmH-kUIb43CviOetK-ZjGl0AnSog",
+ ];
+ beforeEach(() => {
+ mockUserRepository.updateUser = jest.fn(() => "ok");
+ });
+ it("should throw error 400", async () => {
+ mockSpotifyRepository.getToken = jest.fn(() => {
+ return { error: "some error" };
+ });
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/authWithSpotify",
+ payload: {
+ spotify_code: "eztgergrehre",
+ },
+ });
+ expect(res.statusCode).toBe(400);
+ });
+ it("should throw error 403 1", async () => {
+ mockSpotifyRepository.getToken = jest.fn(() => {
+ return {
+ access_token,
+ refresh_token,
+ };
+ });
+ mockSpotifyRepository.getAccountData = jest.fn(() => {
+ return { email, display_name, images };
+ });
+ mockUserRepository.getByEmailOrPseudo = jest.fn(() => {
+ return {
+ confirmed: false,
+ };
+ });
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/authWithSpotify",
+ payload: {
+ spotify_code: "eztgergrehre",
+ callback: "callback",
+ },
+ });
+ expect(res.statusCode).toBe(403);
+ });
+ it("should throw error 403 2", async () => {
+ mockSpotifyRepository.getToken = jest.fn(() => {
+ return {
+ access_token,
+ refresh_token,
+ };
+ });
+ mockSpotifyRepository.getAccountData = jest.fn(() => {
+ return { email, display_name, images };
+ });
+ mockUserRepository.getByEmailOrPseudo = jest.fn(() => {
+ return {
+ confirmed: true,
+ };
+ });
+ mockAccesTokenManager.generate = jest.fn(() => "expected_token");
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/authWithSpotify",
+ payload: {
+ spotify_code: "eztgergrehre",
+ callback: "callback",
+ },
+ });
+ expect(res.statusCode).toBe(403);
+ });
+ it("should return auth token", async () => {
+ mockSpotifyRepository.getToken = jest.fn(() => {
+ return {
+ access_token,
+ refresh_token,
+ };
+ });
+ mockSpotifyRepository.getAccountData = jest.fn(() => {
+ return { email, display_name, images };
+ });
+ mockUserRepository.getByEmailOrPseudo = jest.fn(() => {
+ return {
+ confirmed: true,
+ refresh_token: "someting",
+ };
+ });
+ mockAccesTokenManager.generate = jest.fn(() => "expected_token");
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/authWithSpotify",
+ payload: {
+ spotify_code: "eztgergrehre",
+ callback: "callback",
+ },
+ });
+ expect(res.statusCode).toBe(200);
+ });
+ });
+ describe("/users/status", () => {
+ mockAccesTokenManager.decode = jest.fn((token) => {
+ return { value: 1 };
+ });
+ mockUserRepository.changePrivateStatus = jest.fn((id) => {
+ return new User({
+ id_utilisateur: 1,
+ pseudo: "pseudo",
+ email: "test@test.fr",
+ password: "hjkklllllm",
+ id_role: 1,
+ });
+ });
+ it("should return valid code 200", async () => {
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/status",
+ headers: {
+ Authorization: `Bearer ${mockToken}`,
+ },
+ });
+ expect(res.statusCode).toBe(200);
+ expect(mockUserRepository.changePrivateStatus).toHaveBeenCalledTimes(1);
+ });
+ });
+
+ describe("/users/oeuvreFav", () => {
+ afterEach(() => {
+ jest.clearAllMocks();
+ });
+
+ const {
+ albumRawOneArtist,
+ } = require("../unit/interfaces/serializers/fixtures/albumFixture.js");
+ const {
+ rawTrackWithOneArtist,
+ } = require("../unit/interfaces/serializers/fixtures/albumTrackFixture.js");
+
+ // login erreur
+ it("should return error code 401", async () => {
+ mockAccesTokenManager.decode = jest.fn(() => {
+ return { id: 1 };
+ });
+ mockUserRepository.getByUser = jest.fn(() => null);
+
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/oeuvreFav",
+ payload: {
+ idOeuvre: "test",
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`,
+ },
+ });
+ expect(res.statusCode).toBe(401);
+ });
+
+ // payload incorrect avec entity
+ it("should return error code 400", async () => {
+ mockAccesTokenManager.decode = jest.fn(() => {
+ return { id: 1 };
+ });
+ mockUserRepository.getByUser = jest.fn(() => 1);
+
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/oeuvreFav",
+ payload: {
+ idOeuvre: null,
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`,
+ },
+ });
+ expect(res.statusCode).toBe(400);
+ });
+
+ // payload incorrect avec entity
+ it("should return error code 400", async () => {
+ mockAccesTokenManager.decode = jest.fn(() => {
+ return { id: 1 };
+ });
+ mockUserRepository.getByUser = jest.fn(() => 1);
+
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/oeuvreFav",
+ payload: {
+ idOeuvre: 123, // doit être un string
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`,
+ },
+ });
+ expect(res.statusCode).toBe(400);
+ });
+ // aucune oeuvre de trouve
+ it("should return error code 404", async () => {
+ mockAccesTokenManager.decode = jest.fn(() => {
+ return { id: 1 };
+ });
+ mockUserRepository.getByUser = jest.fn(() => 1);
+ mockSpotifyRepository.getOeuvre = jest.fn((idOeuvre) => {
+ return { error: { status: 404, message: "invalid id" } };
+ });
+
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/oeuvreFav",
+ payload: {
+ idOeuvre: "test1323",
+ type: "track",
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`,
+ },
+ });
+ expect(res.statusCode).toBe(404);
+ expect(mockSpotifyRepository.getOeuvre).toHaveBeenCalledTimes(1);
+ });
+
+ // plus de 3 oeuvres favorites avec album
+ it("should return error code 403 1", async () => {
+ mockAccesTokenManager.decode = jest.fn(() => {
+ return { id: 1 };
+ });
+ mockUserRepository.getByUser = jest.fn(() => 1);
+ mockSpotifyRepository.getOeuvre = jest.fn((idOeuvre) => {
+ return Promise.resolve(albumRawOneArtist);
+ });
+ mockOeuvreFavRepository.oeuvreFavExists = jest.fn(
+ (id_utilisateur, idOeuvre) => false
+ );
+ mockOeuvreFavRepository.ajoutPossible = jest.fn(
+ (id_utilisateur, idOeuvre) => false
+ );
+
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/oeuvreFav",
+ payload: {
+ idOeuvre: "test123", // doit être un string
+ type: "album",
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`,
+ },
+ });
+
+ expect(mockOeuvreFavRepository.ajoutPossible).toHaveBeenCalledTimes(1);
+ expect(res.statusCode).toBe(403);
+ });
+
+ // plus de 3 oeuvres favorites avec track
+ it("should return error code 403 2", async () => {
+ mockAccesTokenManager.decode = jest.fn(() => {
+ return { id: 1 };
+ });
+ mockUserRepository.getByUser = jest.fn(() => 1);
+
+ mockSpotifyRepository.getOeuvre = jest.fn((idOeuvre) => {
+ return Promise.resolve(rawTrackWithOneArtist);
+ });
+ mockOeuvreFavRepository.oeuvreFavExists = jest.fn(
+ (id_utilisateur, idOeuvre) => false
+ );
+ mockOeuvreFavRepository.ajoutPossible = jest.fn(
+ (id_utilisateur, idOeuvre) => false
+ );
+
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/oeuvreFav",
+ payload: {
+ idOeuvre: "test123",
+ type: "track",
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`,
+ },
+ });
+
+ // expect(mockSpotifyRepository.getSpotifyTracks).toHaveBeenCalledTimes(1);
+ // expect(mockOeuvreFavRepository.ajoutPossible).toHaveBeenCalledTimes(1);
+ expect(res.statusCode).toBe(403);
+ });
+
+ // ajout réussie avec album
+ it("should return code 200 1", async () => {
+ mockAccesTokenManager.decode = jest.fn(() => {
+ return { id: 1 };
+ });
+ mockUserRepository.getByUser = jest.fn(() => 1);
+ mockSpotifyRepository.getOeuvre = jest.fn((idOeuvre) => {
+ return Promise.resolve(albumRawOneArtist);
+ });
+ mockSpotifyRepository.getSpotifyTracks = jest.fn();
+ mockOeuvreFavRepository.oeuvreFavExists = jest.fn(
+ (id_utilisateur, idOeuvre) => false
+ );
+ mockOeuvreFavRepository.ajoutPossible = jest.fn(
+ (id_utilisateur, idOeuvre) => true
+ );
+ mockOeuvreFavRepository.addOeuvrefav = jest.fn();
+
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/oeuvreFav",
+ payload: {
+ idOeuvre: "test123",
+ type: "track",
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`,
+ },
+ });
+
+ expect(mockSpotifyRepository.getSpotifyTracks).not.toHaveBeenCalled();
+
+ expect(mockOeuvreFavRepository.ajoutPossible).toHaveBeenCalledTimes(1);
+ expect(mockOeuvreFavRepository.addOeuvrefav).toHaveBeenCalledTimes(1);
+ expect(res.statusCode).toBe(200);
+ });
+
+ // ajout réussie avec track
+ it("should return code 200 2", async () => {
+ mockAccesTokenManager.decode = jest.fn(() => {
+ return { id: 1 };
+ });
+ mockUserRepository.getByUser = jest.fn(() => 1);
+
+ mockSpotifyRepository.getOeuvre = jest.fn((idOeuvre) => {
+ return Promise.resolve(rawTrackWithOneArtist);
+ });
+ mockOeuvreFavRepository.oeuvreFavExists = jest.fn(
+ (id_utilisateur, idOeuvre) => false
+ );
+ mockOeuvreFavRepository.ajoutPossible = jest.fn(
+ (id_utilisateur, idOeuvre) => true
+ );
+ mockOeuvreFavRepository.addOeuvrefav = jest.fn();
+
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/oeuvreFav",
+ payload: {
+ idOeuvre: "test123",
+ type: "track",
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`,
+ },
+ });
+
+ expect(mockOeuvreFavRepository.ajoutPossible).toHaveBeenCalledTimes(1);
+ expect(mockOeuvreFavRepository.addOeuvrefav).toHaveBeenCalledTimes(1);
+ expect(res.statusCode).toBe(200);
+ });
+
+ // supression reussite avec album
+ it("should return code 200 3 ", async () => {
+ mockAccesTokenManager.decode = jest.fn(() => {
+ return { id: 1 };
+ });
+ mockUserRepository.getByUser = jest.fn(() => 1);
+ mockSpotifyRepository.getOeuvre = jest.fn((idOeuvre) => {
+ return Promise.resolve(albumRawOneArtist);
+ });
+
+ mockSpotifyRepository.getSpotifyTracks = jest.fn();
+ mockOeuvreFavRepository.oeuvreFavExists = jest.fn(
+ (id_utilisateur, idOeuvre) => true
+ );
+ mockOeuvreFavRepository.ajoutPossible = jest.fn();
+ mockOeuvreFavRepository.addOeuvrefav = jest.fn();
+ mockOeuvreFavRepository.deleteOeuvrefav = jest.fn();
+
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/oeuvreFav",
+ payload: {
+ idOeuvre: "test123",
+ type: "track",
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`,
+ },
+ });
+
+ expect(mockSpotifyRepository.getSpotifyTracks).not.toHaveBeenCalled();
+
+ expect(mockOeuvreFavRepository.ajoutPossible).not.toHaveBeenCalled();
+ expect(res.statusCode).toBe(200);
+ });
+
+ // supression reussite avec track
+ it("should return code 200 4", async () => {
+ mockAccesTokenManager.decode = jest.fn(() => {
+ return { id: 1 };
+ });
+ mockUserRepository.getByUser = jest.fn(() => 1);
+ mockSpotifyRepository.getOeuvre = jest.fn((idOeuvre) => {
+ return Promise.resolve(rawTrackWithOneArtist);
+ });
+ mockOeuvreFavRepository.oeuvreFavExists = jest.fn(
+ (id_utilisateur, idOeuvre) => true
+ );
+ mockOeuvreFavRepository.ajoutPossible = jest.fn();
+ mockOeuvreFavRepository.addOeuvrefav = jest.fn();
+ mockOeuvreFavRepository.deleteOeuvrefav = jest.fn();
+
+ const res = await server.inject({
+ method: "POST",
+ url: "/users/oeuvreFav",
+ payload: {
+ idOeuvre: "test123",
+ type: "track",
+ },
+ headers: {
+ Authorization: `Bearer ${mockToken}`,
+ },
+ });
+
+ expect(mockOeuvreFavRepository.ajoutPossible).not.toHaveBeenCalled();
+ expect(res.statusCode).toBe(200);
+ });
+ });
+
+ describe("/users/getOeuvresFav", () => {
+ afterEach(() => {
+ jest.clearAllMocks();
+ });
+ it("should return error code 401", async () => {
+ mockAccesTokenManager.decode = jest.fn(() => {
+ return { id: 1 };
+ });
+ mockUserRepository.getByUser = jest.fn(() => null);
+
+ const res = await server.inject({
+ method: "GET",
+ url: "/users/getOeuvresFav",
+ headers: {
+ Authorization: `Bearer ${mockToken}`,
+ },
+ });
+ expect(res.statusCode).toBe(401);
+ });
+ });
+ it("should return code 200", async () => {
+ mockAccesTokenManager.decode = jest.fn(() => {
+ return { id: 1 };
+ });
+ mockUserRepository.getByUser = jest.fn(() => 1);
+ mockOeuvreFavRepository.getOeuvresFav = jest.fn((id) => {
+ return [1, 2, 3];
+ });
+ const res = await server.inject({
+ method: "GET",
+ url: "/users/getOeuvresFav",
+ headers: {
+ Authorization: `Bearer ${mockToken}`,
+ },
+ });
+ expect(res.statusCode).toBe(200);
+ });
+
+ it("should return code 200 ", async () => {
+ mockAccesTokenManager.decode = jest.fn(() => {
+ return { id: 1 };
+ });
+ mockUserRepository.getByUser = jest.fn(() => 1);
+ mockOeuvreFavRepository.getOeuvresFav = jest.fn((id) => {
+ return [];
+ });
+ const res = await server.inject({
+ method: "GET",
+ url: "/users/getOeuvresFav",
+ headers: {
+ Authorization: `Bearer ${mockToken}`,
+ },
+ });
+ expect(res.statusCode).toBe(200);
+ });
});
diff --git a/test/unit/application/usecase/artist/getArtist.test.js b/test/unit/application/usecase/artist/getArtist.test.js
new file mode 100644
index 0000000..14a86aa
--- /dev/null
+++ b/test/unit/application/usecase/artist/getArtist.test.js
@@ -0,0 +1,126 @@
+const getArtist = require("./../../../../../lib/application/use_cases/artist/getArtist")
+const catchError = require("../utils/catchError")
+const {
+ mockUser,
+ mockArtist,
+ mockUserPrivate,
+ mockAlbumRaw,
+ mockLikedReview,
+ mockCommentedReview,
+ mockOeuvreReviewSpotify,
+ expectedArtist
+} = require('./getArtistFixture')
+describe("getArtist Test", ()=>{
+ const mockReviewRepository = {}
+ const mockAccesTokenManager = {}
+ const mockUserRepository = {}
+ const mockSpotifyRepository = {}
+ const mockFollowRepository = {}
+ const serviceLocator = {
+ reviewRepository: mockReviewRepository,
+ accessTokenManager: mockAccesTokenManager,
+ userRepository: mockUserRepository,
+ spotifyRepository: mockSpotifyRepository,
+ followRepository: mockFollowRepository,
+ }
+ describe("valid cases", ()=>{
+ it("should return valid artist", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((id) => mockUser)
+ mockFollowRepository.getFollowersCount = jest.fn((artistId) => 100)
+ mockFollowRepository.getFriendsFollowing = jest.fn((artistId,userId,limit) => [mockUserPrivate])
+ mockFollowRepository.getFriendsFollowingCount = jest.fn((artistId,userId) => 1)
+ mockSpotifyRepository.getSpotifyArtist = jest.fn((artistId) => mockArtist)
+ mockSpotifyRepository.getSpotifyArtistSongs = jest.fn((artistId,filter,limit) => mockAlbumRaw)
+ mockReviewRepository.getOeuvreRating = jest.fn((id) => 1)
+ mockReviewRepository.getReviewCount = jest.fn((id) => 2)
+ mockReviewRepository.getOeuvreReviews = jest.fn().mockReturnValueOnce([mockLikedReview]).mockReturnValueOnce([mockCommentedReview])
+ mockreviewRepository.doesUserLikes = jest.fn().mockReturnValue(true)
+ mockFollowRepository.doesFollows = jest.fn().mockReturnValue(true)
+ mockSpotifyRepository.getOeuvre = jest.fn().mockReturnValue(mockOeuvreReviewSpotify)
+ const result = await getArtist(1,'token', serviceLocator)
+ result.albums[0].popularity = 64
+ expect(result).toEqual(expectedArtist)
+ })
+ })
+ describe("invalid cases", ()=>{
+ it("should throw error bad auth token", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((id) => null)
+ const error = await catchError(async ()=>{
+ await getArtist(1,'token', serviceLocator)
+ })
+ expect(error.code).toBe(401)
+ })
+ it("should throw error artist not found", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((id) => mockUser)
+ mockSpotifyRepository.getSpotifyArtist = jest.fn((artistId) => {
+ return {
+ error: {
+ status: 400,
+ message: "message",
+ }
+ }
+ })
+ const error = await catchError(async ()=>{
+ await getArtist(1,'token', serviceLocator)
+ })
+ expect(error.code).toBe(400)
+ })
+
+ it("should throw error oeuvre not found 1", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((id) => mockUser)
+ mockFollowRepository.getFollowersCount = jest.fn((artistId) => 100)
+ mockFollowRepository.getFriendsFollowing = jest.fn((artistId,userId,limit) => [mockUserPrivate])
+ mockFollowRepository.getFriendsFollowingCount = jest.fn((artistId,userId) => 1)
+ mockSpotifyRepository.getSpotifyArtist = jest.fn((artistId) => mockArtist)
+ mockSpotifyRepository.getSpotifyArtistSongs = jest.fn((artistId,filter,limit) => mockAlbumRaw)
+ mockReviewRepository.getOeuvreRating = jest.fn((id) => 1)
+ mockReviewRepository.getReviewCount = jest.fn((id) => 2)
+ mockReviewRepository.getOeuvreReviews = jest.fn().mockReturnValueOnce([mockLikedReview]).mockReturnValueOnce([mockCommentedReview])
+ mockreviewRepository.doesUserLikes = jest.fn().mockReturnValue(true)
+ mockFollowRepository.doesFollows = jest.fn().mockReturnValue(true)
+ mockSpotifyRepository.getOeuvre = jest.fn().mockReturnValue({
+ error: {
+ status: 400,
+ message: "message",
+ }
+ })
+
+ const error = await catchError(async ()=>{
+ await getArtist(1,'token', serviceLocator)
+ })
+ expect(error.code).toBe(400)
+ })
+
+ it("should throw error oeuvre not found 2", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((id) => mockUser)
+ mockFollowRepository.getFollowersCount = jest.fn((artistId) => 100)
+ mockFollowRepository.getFriendsFollowing = jest.fn((artistId,userId,limit) => [mockUserPrivate])
+ mockFollowRepository.getFriendsFollowingCount = jest.fn((artistId,userId) => 1)
+ mockSpotifyRepository.getSpotifyArtist = jest.fn((artistId) => mockArtist)
+ mockSpotifyRepository.getSpotifyArtistSongs = jest.fn((artistId,filter,limit) => mockAlbumRaw)
+ mockReviewRepository.getOeuvreRating = jest.fn((id) => 1)
+ mockReviewRepository.getReviewCount = jest.fn((id) => 2)
+ mockReviewRepository.getOeuvreReviews = jest.fn().mockReturnValueOnce([mockLikedReview]).mockReturnValueOnce([mockCommentedReview])
+ mockreviewRepository.doesUserLikes = jest.fn().mockReturnValue(true)
+ mockFollowRepository.doesFollows = jest.fn().mockReturnValue(true)
+ mockSpotifyRepository.getOeuvre = jest.fn().mockReturnValueOnce(mockOeuvreReviewSpotify).mockReturnValue({
+ error: {
+ status: 400,
+ message: "message",
+ }
+ })
+
+ const error = await catchError(async ()=>{
+ await getArtist(1,'token', serviceLocator)
+ })
+ expect(error.code).toBe(400)
+ })
+
+ })
+
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/artist/getArtistFixture.js b/test/unit/application/usecase/artist/getArtistFixture.js
new file mode 100644
index 0000000..4f2c7b2
--- /dev/null
+++ b/test/unit/application/usecase/artist/getArtistFixture.js
@@ -0,0 +1,405 @@
+const mockArtist = {
+ external_urls: {
+ spotify: "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",
+ },
+ genres: ["french hip hop", "old school rap francais", "rap conscient"],
+ id: "4FpJcNgOvIpSBeJgRg3OfN",
+ images: [
+ {
+ height: 640,
+ url: "https://i.scdn.co/image/ab6761610000e5eb32086a424e6f1e499e347cde",
+ width: 640,
+ },
+ ],
+ name: "Orelsan",
+ popularity: 64,
+ type: "artist",
+};
+const mockAlbumRaw = {
+ href: "https://api.spotify.com/v1/artists/4FpJcNgOvIpSBeJgRg3OfN/albums?include_groups=album,single&offset=0&limit=10",
+ items: [
+ {
+ album_group: "album",
+ album_type: "album",
+ artists: [
+ {
+ external_urls: {
+ spotify: "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",
+ },
+ id: "4FpJcNgOvIpSBeJgRg3OfN",
+ name: "Orelsan",
+ type: "artist",
+ },
+ ],
+ external_urls: {
+ spotify: "https://open.spotify.com/album/68YP0pEgwhnfRqQAzu71gP",
+ },
+ id: "68YP0pEgwhnfRqQAzu71gP",
+ images: [
+ {
+ height: 640,
+ url: "https://i.scdn.co/image/ab67616d0000b2732724364cd86bb791926b6cc8",
+ width: 640,
+ },
+ ],
+ name: "Civilisation Edition Ultime",
+ release_date: "2022-10-28",
+ total_tracks: 25,
+ type: "album",
+ },
+ ],
+};
+const mockUser = {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false,
+};
+
+const mockUserPrivate = {
+ pseudo: "John Doe2",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ id_utilisateur: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: true,
+};
+const actualDate = new Date();
+
+const mockLikedReview = {
+ id_review: 25,
+ id_oeuvre: "68YP0pEgwhnfRqQAzu71gP",
+ countlikes: 32,
+ countComment: 0,
+ description:
+ "Innovation sonore à son apogée, repoussant les limites de l'expérimentation musicale. #AvantGarde #SoundExploration",
+ note: 5,
+ createdAt: "2024-01-03T00:00:00.000Z",
+ updated_at: "2024-01-03T00:00:00.000Z",
+ type: "album",
+ utilisateur: {
+ id_utilisateur: 54,
+ pseudo: "Constance",
+ email: "Constance.Constance@gmail.com",
+ alias: "Constance",
+ photo: "https://ozgrozer.github.io/100k-faces/0/6/006026.jpg",
+ photo_temporaire: null,
+ token: null,
+ refresh_token: null,
+ reset_token: null,
+ password: "$2b$10$feqJS.qjWmoYovS805Mmhu.7VjOncR68em0Bu4LSxS/4tDSP8HWK2",
+ id_role: 1,
+ ban_until: null,
+ confirmed: true,
+ confirm_token: null,
+ auth_with_spotify: false,
+ is_private: true,
+ type: "user",
+ },
+};
+
+const mockCommentedReview = {
+ id_review: 25,
+ id_oeuvre: "68YP0pEgwhnfRqQAzu71gP",
+ countlikes: 32,
+ countComment: 0,
+ description:
+ "Innovation sonore à son apogée, repoussant les limites de l'expérimentation musicale. #AvantGarde #SoundExploration",
+ note: 5,
+ createdAt: "2024-01-03T00:00:00.000Z",
+ updated_at: "2024-01-03T00:00:00.000Z",
+ type: "album",
+ utilisateur: {
+ id_utilisateur: 54,
+ pseudo: "Constance",
+ email: "Constance.Constance@gmail.com",
+ alias: "Constance",
+ photo: "https://ozgrozer.github.io/100k-faces/0/6/006026.jpg",
+ photo_temporaire: null,
+ token: null,
+ refresh_token: null,
+ reset_token: null,
+ password: "$2b$10$feqJS.qjWmoYovS805Mmhu.7VjOncR68em0Bu4LSxS/4tDSP8HWK2",
+ id_role: 1,
+ ban_until: null,
+ confirmed: true,
+ confirm_token: null,
+ auth_with_spotify: false,
+ is_private: true,
+ type: "user",
+ },
+};
+
+const mockOeuvreReviewSpotify = {
+ album_type: "album",
+ artists: [
+ {
+ external_urls: {
+ spotify: "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",
+ },
+ id: "4FpJcNgOvIpSBeJgRg3OfN",
+ name: "Orelsan",
+ type: "artist",
+ },
+ ],
+
+ external_urls: {
+ spotify: "https://open.spotify.com/album/68YP0pEgwhnfRqQAzu71gP",
+ },
+ genres: [],
+ id: "68YP0pEgwhnfRqQAzu71gP",
+ images: [
+ {
+ height: 640,
+ url: "https://i.scdn.co/image/ab67616d0000b2732724364cd86bb791926b6cc8",
+ width: 640,
+ },
+ ],
+ name: "Civilisation Edition Ultime",
+ popularity: 60,
+ release_date: "2022-10-28",
+ total_tracks: 1,
+ tracks: {
+ href: "https://api.spotify.com/v1/albums/68YP0pEgwhnfRqQAzu71gP/tracks?offset=0&limit=50",
+ items: [
+ {
+ artists: [
+ {
+ external_urls: {
+ spotify: "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",
+ },
+ href: "https://api.spotify.com/v1/artists/4FpJcNgOvIpSBeJgRg3OfN",
+ id: "4FpJcNgOvIpSBeJgRg3OfN",
+ name: "Orelsan",
+ type: "artist",
+ uri: "spotify:artist:4FpJcNgOvIpSBeJgRg3OfN",
+ },
+ ],
+
+ disc_number: 1,
+ duration_ms: 161732,
+ external_urls: {
+ spotify: "https://open.spotify.com/track/7b3YQboXo3kau9YVUyx3r4",
+ },
+ id: "7b3YQboXo3kau9YVUyx3r4",
+ name: "CP_001_ Intro Civilisation Perdue",
+ preview_url:
+ "https://p.scdn.co/mp3-preview/b7f3ef4f7ee54bcba700a821952539b7e4e21d2f?cid=24b7c8fbb7d146edbce14e1743cea479",
+ track_number: 1,
+ type: "track",
+ },
+ ],
+ total: 25,
+ },
+ type: "album",
+};
+
+const expectedArtist = {
+ artist: {
+ id: "4FpJcNgOvIpSBeJgRg3OfN",
+ name: "Orelsan",
+ image: "https://i.scdn.co/image/ab6761610000e5eb32086a424e6f1e499e347cde",
+ popularity: 64,
+ follower_count: 100,
+ genres: ["french hip hop", "old school rap francais", "rap conscient"],
+ spotify_url: "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",
+ type: "artist",
+ },
+ albums: [
+ {
+ id: "68YP0pEgwhnfRqQAzu71gP",
+ name: "Civilisation Edition Ultime",
+ popularity: 64,
+ rating: 1,
+ reviewCount: 2,
+ release_date: "2022-10-28",
+ total_tracks: 25,
+ image: "https://i.scdn.co/image/ab67616d0000b2732724364cd86bb791926b6cc8",
+ spotify_url: "https://open.spotify.com/album/68YP0pEgwhnfRqQAzu71gP",
+ artists: [
+ {
+ id: "4FpJcNgOvIpSBeJgRg3OfN",
+ name: "Orelsan",
+ image: null,
+ spotify_url: "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",
+ type: "artist",
+ },
+ ],
+ type: "album",
+ },
+ ],
+ friends_followers: {
+ count: 1,
+ users: [
+ {
+ id_utilisateur: 1,
+ pseudo: "John Doe2",
+ email: "testemail@gmail",
+ alias: "John",
+ photo: null,
+ photo_temporaire: null,
+ id_role: 1,
+ ban_until: null,
+ is_private: true,
+ type: "user",
+ },
+ ],
+ },
+ reviewsByLike: [
+ {
+ id_review: 25,
+ description:
+ "Innovation sonore à son apogée, repoussant les limites de l'expérimentation musicale. #AvantGarde #SoundExploration",
+ countlikes: 32,
+ countComment: 0,
+ doesUserLike: true,
+ createdAt: "2024-01-03T00:00:00.000Z",
+ note: 5,
+ oeuvre: {
+ id: "68YP0pEgwhnfRqQAzu71gP",
+ name: "Civilisation Edition Ultime",
+ popularity: 60,
+ release_date: "2022-10-28",
+ total_tracks: 1,
+ image:
+ "https://i.scdn.co/image/ab67616d0000b2732724364cd86bb791926b6cc8",
+ spotify_url: "https://open.spotify.com/album/68YP0pEgwhnfRqQAzu71gP",
+ artists: [
+ {
+ id: "4FpJcNgOvIpSBeJgRg3OfN",
+ name: "Orelsan",
+ image: null,
+ spotify_url:
+ "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",
+ type: "artist",
+ },
+ ],
+ tracks: [
+ {
+ id: "7b3YQboXo3kau9YVUyx3r4",
+ name: "CP_001_ Intro Civilisation Perdue",
+ artists: [
+ {
+ id: "4FpJcNgOvIpSBeJgRg3OfN",
+ name: "Orelsan",
+ image: null,
+ spotify_url:
+ "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",
+ type: "artist",
+ },
+ ],
+ duration_ms: 161732,
+ spotify_url:
+ "https://open.spotify.com/track/7b3YQboXo3kau9YVUyx3r4",
+ type: "track",
+ },
+ ],
+ genres: [],
+ type: "album",
+ },
+ utilisateur: {
+ id_utilisateur: 54,
+ pseudo: "Constance",
+ auth_with_spotify: false,
+ email: "Constance.Constance@gmail.com",
+ alias: "Constance",
+ photo: "https://ozgrozer.github.io/100k-faces/0/6/006026.jpg",
+ photo_temporaire: null,
+ id_role: 1,
+ ban_until: null,
+ is_private: true,
+ type: "user",
+ },
+ type: "album",
+ },
+ ],
+ reviewsByTime: [
+ {
+ id_review: 25,
+ description:
+ "Innovation sonore à son apogée, repoussant les limites de l'expérimentation musicale. #AvantGarde #SoundExploration",
+ countlikes: 32,
+ createdAt: "2024-01-03T00:00:00.000Z",
+ countComment: 0,
+ doesUserLike: true,
+ note: 5,
+ oeuvre: {
+ id: "68YP0pEgwhnfRqQAzu71gP",
+ name: "Civilisation Edition Ultime",
+ popularity: 60,
+ release_date: "2022-10-28",
+ total_tracks: 1,
+ image:
+ "https://i.scdn.co/image/ab67616d0000b2732724364cd86bb791926b6cc8",
+ spotify_url: "https://open.spotify.com/album/68YP0pEgwhnfRqQAzu71gP",
+ artists: [
+ {
+ id: "4FpJcNgOvIpSBeJgRg3OfN",
+ name: "Orelsan",
+ image: null,
+ spotify_url:
+ "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",
+ type: "artist",
+ },
+ ],
+ tracks: [
+ {
+ id: "7b3YQboXo3kau9YVUyx3r4",
+ name: "CP_001_ Intro Civilisation Perdue",
+ artists: [
+ {
+ id: "4FpJcNgOvIpSBeJgRg3OfN",
+ name: "Orelsan",
+ image: null,
+ spotify_url:
+ "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",
+ type: "artist",
+ },
+ ],
+ duration_ms: 161732,
+ spotify_url:
+ "https://open.spotify.com/track/7b3YQboXo3kau9YVUyx3r4",
+ type: "track",
+ },
+ ],
+ genres: [],
+ type: "album",
+ },
+ utilisateur: {
+ id_utilisateur: 54,
+ pseudo: "Constance",
+ auth_with_spotify: false,
+ email: "Constance.Constance@gmail.com",
+ alias: "Constance",
+ photo: "https://ozgrozer.github.io/100k-faces/0/6/006026.jpg",
+ photo_temporaire: null,
+ id_role: 1,
+ ban_until: null,
+ is_private: true,
+ type: "user",
+ },
+ type: "album",
+ },
+ ],
+ doesUserFollow: true,
+};
+module.exports = {
+ mockUser,
+ mockArtist,
+ mockUserPrivate,
+ mockAlbumRaw,
+ mockLikedReview,
+ mockCommentedReview,
+ mockOeuvreReviewSpotify,
+ expectedArtist,
+};
diff --git a/test/unit/application/usecase/fixtures/fetchArtist.js b/test/unit/application/usecase/fixtures/fetchArtist.js
new file mode 100644
index 0000000..e5a2891
--- /dev/null
+++ b/test/unit/application/usecase/fixtures/fetchArtist.js
@@ -0,0 +1,12 @@
+const {
+ artistFixture,
+ expectedFixture
+} = require("../../../interfaces/serializers/fixtures/artistFixture")
+
+artistFixture.popularity = 2
+expectedFixture.popularity = 2
+
+module.exports = {
+ artistFixture,
+ expectedFixture,
+}
\ No newline at end of file
diff --git a/test/unit/application/usecase/fixtures/getOeuvreFixture.js b/test/unit/application/usecase/fixtures/getOeuvreFixture.js
new file mode 100644
index 0000000..bbda437
--- /dev/null
+++ b/test/unit/application/usecase/fixtures/getOeuvreFixture.js
@@ -0,0 +1,394 @@
+const mockArtist = {
+ external_urls: { spotify: 'https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN' },
+ genres: [ 'french hip hop', 'old school rap francais', 'rap conscient' ],
+ id: '4FpJcNgOvIpSBeJgRg3OfN',
+ images: [
+ {
+ height: 640,
+ url: 'https://i.scdn.co/image/ab6761610000e5eb32086a424e6f1e499e347cde',
+ width: 640
+ },
+ ],
+ name: 'Orelsan',
+ popularity: 64,
+ type: 'artist',
+ }
+const mockAlbumRaw = {
+ "href": "https://api.spotify.com/v1/artists/4FpJcNgOvIpSBeJgRg3OfN/albums?include_groups=album,single&offset=0&limit=10",
+ "items": [
+ {
+ "album_group": "album",
+ "album_type": "album",
+ "artists": [
+ {
+ "external_urls": {
+ "spotify": "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN"
+ },
+ "id": "4FpJcNgOvIpSBeJgRg3OfN",
+ "name": "Orelsan",
+ "type": "artist"
+ }
+ ],
+ "external_urls": {
+ "spotify": "https://open.spotify.com/album/68YP0pEgwhnfRqQAzu71gP"
+ },
+ "id": "68YP0pEgwhnfRqQAzu71gP",
+ "images": [
+ {
+ "height": 640,
+ "url": "https://i.scdn.co/image/ab67616d0000b2732724364cd86bb791926b6cc8",
+ "width": 640
+ }
+ ],
+ "name": "Civilisation Edition Ultime",
+ "release_date": "2022-10-28",
+ "total_tracks": 25,
+ "type": "album"
+ }
+ ]
+}
+const mockUser = {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+}
+
+const mockUserPrivate = {
+ pseudo: "John Doe2",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ id_utilisateur: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: true
+}
+const actualDate = new Date()
+
+
+const mockLikedReview = {
+ "id_review": 25,
+ "id_oeuvre": "68YP0pEgwhnfRqQAzu71gP",
+ "countlikes": 32,
+ "countComment": 0,
+ "description": "Innovation sonore à son apogée, repoussant les limites de l'expérimentation musicale. #AvantGarde #SoundExploration",
+ "note": 5,
+ "createdAt": "2024-01-03T00:00:00.000Z",
+ "updated_at": "2024-01-03T00:00:00.000Z",
+ "type": "album",
+ "utilisateur": {
+ "id_utilisateur": 54,
+ "pseudo": "Constance",
+ "email": "Constance.Constance@gmail.com",
+ "alias": "Constance",
+ "photo": "https://ozgrozer.github.io/100k-faces/0/6/006026.jpg",
+ "photo_temporaire": null,
+ "token": null,
+ "refresh_token": null,
+ "reset_token": null,
+ "password": "$2b$10$feqJS.qjWmoYovS805Mmhu.7VjOncR68em0Bu4LSxS/4tDSP8HWK2",
+ "id_role": 1,
+ "ban_until": null,
+ "confirmed": true,
+ "confirm_token": null,
+ "auth_with_spotify": false,
+ "is_private": true,
+ "type": "user"
+ }
+}
+
+const mockCommentedReview = {
+ "id_review": 25,
+ "id_oeuvre": "68YP0pEgwhnfRqQAzu71gP",
+ "countlikes": 32,
+ "countComment": 0,
+ "description": "Innovation sonore à son apogée, repoussant les limites de l'expérimentation musicale. #AvantGarde #SoundExploration",
+ "note": 5,
+ "createdAt": "2024-01-03T00:00:00.000Z",
+ "updated_at": "2024-01-03T00:00:00.000Z",
+ "type": "album",
+ "utilisateur": {
+ "id_utilisateur": 54,
+ "pseudo": "Constance",
+ "email": "Constance.Constance@gmail.com",
+ "alias": "Constance",
+ "photo": "https://ozgrozer.github.io/100k-faces/0/6/006026.jpg",
+ "photo_temporaire": null,
+ "token": null,
+ "refresh_token": null,
+ "reset_token": null,
+ "password": "$2b$10$feqJS.qjWmoYovS805Mmhu.7VjOncR68em0Bu4LSxS/4tDSP8HWK2",
+ "id_role": 1,
+ "ban_until": null,
+ "confirmed": true,
+ "confirm_token": null,
+ "auth_with_spotify": false,
+ "is_private": true,
+ "type": "user"
+ }
+}
+
+const mockOeuvreReviewSpotify = {
+ "album_type": "album",
+ "artists": [
+ {
+ "external_urls": {
+ "spotify": "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN"
+ },
+ "id": "4FpJcNgOvIpSBeJgRg3OfN",
+ "name": "Orelsan",
+ "type": "artist"
+ }
+ ],
+
+ "external_urls": {
+ "spotify": "https://open.spotify.com/album/68YP0pEgwhnfRqQAzu71gP"
+ },
+ "genres": [],
+ "id": "68YP0pEgwhnfRqQAzu71gP",
+ "images": [
+ {
+ "height": 640,
+ "url": "https://i.scdn.co/image/ab67616d0000b2732724364cd86bb791926b6cc8",
+ "width": 640
+ }
+ ],
+ "name": "Civilisation Edition Ultime",
+ "popularity": 60,
+ "release_date": "2022-10-28",
+ "total_tracks": 1,
+ "tracks": {
+ "href": "https://api.spotify.com/v1/albums/68YP0pEgwhnfRqQAzu71gP/tracks?offset=0&limit=50",
+ "items": [
+ {
+ "artists": [
+ {
+ "external_urls": {
+ "spotify": "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN"
+ },
+ "href": "https://api.spotify.com/v1/artists/4FpJcNgOvIpSBeJgRg3OfN",
+ "id": "4FpJcNgOvIpSBeJgRg3OfN",
+ "name": "Orelsan",
+ "type": "artist",
+ "uri": "spotify:artist:4FpJcNgOvIpSBeJgRg3OfN"
+ }
+ ],
+
+ "disc_number": 1,
+ "duration_ms": 161732,
+ "external_urls": {
+ "spotify": "https://open.spotify.com/track/7b3YQboXo3kau9YVUyx3r4"
+ },
+ "id": "7b3YQboXo3kau9YVUyx3r4",
+ "name": "CP_001_ Intro Civilisation Perdue",
+ "preview_url": "https://p.scdn.co/mp3-preview/b7f3ef4f7ee54bcba700a821952539b7e4e21d2f?cid=24b7c8fbb7d146edbce14e1743cea479",
+ "track_number": 1,
+ "type": "track"
+ }
+ ],
+ "total": 25
+ },
+ "type": "album"
+}
+
+
+const expectedArtist = {
+ "artist": {
+ "id": "4FpJcNgOvIpSBeJgRg3OfN",
+ "name": "Orelsan",
+ "image": "https://i.scdn.co/image/ab6761610000e5eb32086a424e6f1e499e347cde",
+ "popularity": 64,
+ "follower_count": 100,
+ "genres": [
+ "french hip hop",
+ "old school rap francais",
+ "rap conscient"
+ ],
+ "spotify_url": "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",
+ "type": "artist"
+ },
+ "albums": [
+ {
+ "id": "68YP0pEgwhnfRqQAzu71gP",
+ "name": "Civilisation Edition Ultime",
+ "popularity": 64,
+ "rating": 1,
+ "reviewCount": 2,
+ "release_date": "2022-10-28",
+ "total_tracks": 25,
+ "image": "https://i.scdn.co/image/ab67616d0000b2732724364cd86bb791926b6cc8",
+ "spotify_url": "https://open.spotify.com/album/68YP0pEgwhnfRqQAzu71gP",
+ "artists": [
+ {
+ "id": "4FpJcNgOvIpSBeJgRg3OfN",
+ "name": "Orelsan",
+ "image": null,
+ "spotify_url": "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",
+ "type": "artist"
+ }
+ ],
+ "type": "album"
+ }
+ ],
+ "friends_followers": {
+ "count": 1,
+ "users": [
+ {
+ "id_utilisateur": 1,
+ "pseudo": "John Doe2",
+ "email": "testemail@gmail",
+ "alias": "John",
+ "photo": null,
+ "photo_temporaire": null,
+ "id_role": 1,
+ "ban_until": null,
+ "is_private": true,
+ "type": "user"
+ }
+ ]
+ },
+ "reviewsByLike": [
+ {
+ "id_review": 25,
+ "description": "Innovation sonore à son apogée, repoussant les limites de l'expérimentation musicale. #AvantGarde #SoundExploration",
+ "countlikes": 32,
+ "countComment": 0,
+ "doesUserLike": true,
+ "createdAt": "2024-01-03T00:00:00.000Z",
+ "note": 5,
+ "oeuvre": {
+ "id": "68YP0pEgwhnfRqQAzu71gP",
+ "name": "Civilisation Edition Ultime",
+ "popularity": 60,
+ "release_date": "2022-10-28",
+ "total_tracks": 1,
+ "image": "https://i.scdn.co/image/ab67616d0000b2732724364cd86bb791926b6cc8",
+ "spotify_url": "https://open.spotify.com/album/68YP0pEgwhnfRqQAzu71gP",
+ "artists": [
+ {
+ "id": "4FpJcNgOvIpSBeJgRg3OfN",
+ "name": "Orelsan",
+ "image": null,
+ "spotify_url": "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",
+ "type": "artist"
+ }
+ ],
+ "tracks": [
+ {
+ "id": "7b3YQboXo3kau9YVUyx3r4",
+ "name": "CP_001_ Intro Civilisation Perdue",
+ "artists": [
+ {
+ "id": "4FpJcNgOvIpSBeJgRg3OfN",
+ "name": "Orelsan",
+ "image": null,
+ "spotify_url": "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",
+ "type": "artist"
+ }
+ ],
+ "duration_ms": 161732,
+ "spotify_url": "https://open.spotify.com/track/7b3YQboXo3kau9YVUyx3r4",
+ "type": "track"
+ }
+ ],
+ "genres": [],
+ "type": "album"
+ },
+ "utilisateur": {
+ "id_utilisateur": 54,
+ "pseudo": "Constance",
+ "email": "Constance.Constance@gmail.com",
+ "alias": "Constance",
+ "photo": "https://ozgrozer.github.io/100k-faces/0/6/006026.jpg",
+ "photo_temporaire": null,
+ "id_role": 1,
+ "ban_until": null,
+ "is_private": true,
+ "type": "user"
+ },
+ "type": "album"
+ }
+ ],
+ "reviewsByTime": [
+ {
+ "id_review": 25,
+ "description": "Innovation sonore à son apogée, repoussant les limites de l'expérimentation musicale. #AvantGarde #SoundExploration",
+ "countlikes": 32,
+ "createdAt": "2024-01-03T00:00:00.000Z",
+ "countComment": 0,
+ "doesUserLike": true,
+ "note": 5,
+ "oeuvre": {
+ "id": "68YP0pEgwhnfRqQAzu71gP",
+ "name": "Civilisation Edition Ultime",
+ "popularity": 60,
+ "release_date": "2022-10-28",
+ "total_tracks": 1,
+ "image": "https://i.scdn.co/image/ab67616d0000b2732724364cd86bb791926b6cc8",
+ "spotify_url": "https://open.spotify.com/album/68YP0pEgwhnfRqQAzu71gP",
+ "artists": [
+ {
+ "id": "4FpJcNgOvIpSBeJgRg3OfN",
+ "name": "Orelsan",
+ "image": null,
+ "spotify_url": "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",
+ "type": "artist"
+ }
+ ],
+ "tracks": [
+ {
+ "id": "7b3YQboXo3kau9YVUyx3r4",
+ "name": "CP_001_ Intro Civilisation Perdue",
+ "artists": [
+ {
+ "id": "4FpJcNgOvIpSBeJgRg3OfN",
+ "name": "Orelsan",
+ "image": null,
+ "spotify_url": "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",
+ "type": "artist"
+ }
+ ],
+ "duration_ms": 161732,
+ "spotify_url": "https://open.spotify.com/track/7b3YQboXo3kau9YVUyx3r4",
+ "type": "track"
+ }
+ ],
+ "genres": [],
+ "type": "album"
+ },
+ "utilisateur": {
+ "id_utilisateur": 54,
+ "pseudo": "Constance",
+ "email": "Constance.Constance@gmail.com",
+ "alias": "Constance",
+ "photo": "https://ozgrozer.github.io/100k-faces/0/6/006026.jpg",
+ "photo_temporaire": null,
+ "id_role": 1,
+ "ban_until": null,
+ "is_private": true,
+ "type": "user"
+ },
+ "type": "album"
+ }
+ ],
+ "doesUserFollow": true
+}
+module.exports = {
+ mockUser,
+ mockArtist,
+ mockUserPrivate,
+ mockAlbumRaw,
+ mockLikedReview,
+ mockCommentedReview,
+ mockOeuvreReviewSpotify,
+ expectedArtist
+}
\ No newline at end of file
diff --git a/test/unit/application/usecase/fixtures/searchFixture.js b/test/unit/application/usecase/fixtures/searchFixture.js
index 049588e..4e0a72f 100644
--- a/test/unit/application/usecase/fixtures/searchFixture.js
+++ b/test/unit/application/usecase/fixtures/searchFixture.js
@@ -11,6 +11,7 @@ const {
rawTrackWithOneArtistOneAlbum,
expectedRawTrackWithOneArtistOneAlbum
} = require("../../../interfaces/serializers/fixtures/trackFixture")
+const {tracks} = require("../../../../../lib/domain/model/Album");
albumRawOneArtist.popularity = 3
artistFixture.popularity = 2
@@ -19,33 +20,84 @@ rawTrackWithOneArtistOneAlbum.popularity = 1
expectedAlbumOneArtist.popularity = 3
expectedFixture.popularity = 2
expectedRawTrackWithOneArtistOneAlbum.popularity = 1
-const mockUser = new User(
- 1,
- 'testPeudo',
- 'testEmail@gmail.com',
- 'test_alias',
- 'testbio',
- 'passwordtest',
- 'spotifyToken',
- 2,
- 1
-)
+
const SpotifyRepositoryFixture = {
tracks : { items : [rawTrackWithOneArtistOneAlbum]},
albums : {items : [albumRawOneArtist]},
artists : {items : [artistFixture]}
}
const expectedSearchResult = [
- expectedAlbumOneArtist,
- expectedFixture,
- expectedRawTrackWithOneArtistOneAlbum,
+ {
+ id: "4FpJcNgOvIpSBeJgRg3OfN",
+ imageURL: "https://i.scdn.co/image/ab67616d0000b2730b2e3999b189fa2a8a6a752f",
+ subtitle: "",
+ title: "Orelsan",
+ type: "artist"
+ },
+ {
+ id: "17UiqpQyl8T8vVxz2Towjy",
+ imageURL: "https://i.scdn.co/image/ab67616d0000b2730b2e3999b189fa2a8a6a752f",
+ subtitle: "Orelsan",
+ title: "Perdu D'Avance",
+ type: "album"
+ },
+
+ {
+ id: "test_id",
+ imageURL: "https://i.scdn.co/image/ab67616d0000b2730b2e3999b189fa2a8a6a752f",
+ subtitle: "Orelsan",
+ title: "test_name",
+ type: "track"
+ },
]
const expectedSearchResultWithUsers = [
- expectedAlbumOneArtist,
- expectedFixture,
- expectedRawTrackWithOneArtistOneAlbum,
- mockUser
+ {
+ id: "4FpJcNgOvIpSBeJgRg3OfN",
+ imageURL: "https://i.scdn.co/image/ab67616d0000b2730b2e3999b189fa2a8a6a752f",
+ subtitle: "",
+ title: "Orelsan",
+ type: "artist"
+ },
+ {
+ id: "17UiqpQyl8T8vVxz2Towjy",
+ imageURL: "https://i.scdn.co/image/ab67616d0000b2730b2e3999b189fa2a8a6a752f",
+ subtitle: "Orelsan",
+ title: "Perdu D'Avance",
+ type: "album"
+ },
+
+ {
+ id: "test_id",
+ imageURL: "https://i.scdn.co/image/ab67616d0000b2730b2e3999b189fa2a8a6a752f",
+ subtitle: "Orelsan",
+ title: "test_name",
+ type: "track"
+ },
+ {
+ id: "id_utilisateur",
+ imageURL: "photo",
+ subtitle: "pseudo",
+ title: "alias",
+ type: "user"
+ }
]
+const mockUser = {
+ id_utilisateur: "id_utilisateur",
+ pseudo: "pseudo",
+ email: "email",
+ alias: "alias",
+ photo: "photo",
+ photo_temporaire: "photo_temporaire",
+ token: "token",
+ refresh_token: "refresh_token",
+ reset_token: "reset_token",
+ password: "password",
+ id_role: "id_role",
+ ban_until: "ban_until",
+ confirmed: "confirmed",
+ confirm_token: "confirm_token",
+ type: "user"
+}
module.exports = {
mockUser,
SpotifyRepositoryFixture,
diff --git a/test/unit/application/usecase/friend/acceptResquestUser.test.js b/test/unit/application/usecase/friend/acceptResquestUser.test.js
new file mode 100644
index 0000000..97311b6
--- /dev/null
+++ b/test/unit/application/usecase/friend/acceptResquestUser.test.js
@@ -0,0 +1,86 @@
+const acceptRequestUser = require('../../../../../lib/application/use_cases/friend/acceptRequestUser')
+const catchError = require("../utils/catchError")
+const mockFriendRepository = {}
+const mockUserRepository = {}
+const mockAccesTokenManager = {}
+
+mockAccesTokenManager.generate = ((test) =>{return ''})
+const relation = {
+ id_utilisateur: 1,
+ amiIdUtilisateur: 2,
+ en_attente: false,
+ createdAt: undefined,
+ updatedAt: undefined,
+ type : 'amis'
+}
+const user = {
+ id_utilisateur : 1,
+ pseudo : "pseudo",
+ email : "test@test.fr",
+ alias : undefined,
+ photo : undefined,
+ photo_temporaire : undefined,
+ token : undefined,
+ refresh_token : undefined,
+ reset_token : undefined,
+ password : "hjkklllllm",
+ id_role : 1,
+ ban_until : undefined,
+ confirmed: undefined,
+ confirm_token : undefined,
+ is_private : true ,
+ type : 'user'
+}
+
+describe("acceptRequestUser", ()=>{
+ afterEach(()=>{
+ jest.clearAllMocks();
+ })
+ beforeEach(()=>{
+ mockUserRepository.getByUser = jest.fn((id)=> {
+ user.id_utilisateur = id
+ return user
+ })
+ mockFriendRepository.accept = jest.fn((id, id_ami) => {
+ return relation
+ })
+ mockAccesTokenManager.decode = jest.fn((token)=> {return {value: 1}})
+ })
+
+ const serviceLocator = {
+ userRepository: mockUserRepository,
+ friendRepository: mockFriendRepository,
+ accessTokenManager:mockAccesTokenManager
+ }
+ it('should accept a request friend of a user', async () => {
+
+ const user = await acceptRequestUser("testtoken",2,serviceLocator)
+ expect(user).toBe(relation)
+ expect(mockUserRepository.getByUser).toHaveBeenCalledTimes(2)
+ expect(mockFriendRepository.accept).toHaveBeenCalledTimes(1)
+ });
+
+ it('should throw error 400 invalid id friend', async () => {
+ mockUserRepository.getByUser = jest.fn((id)=> {
+ return null
+ })
+ const error = await catchError(async ()=>{
+ await acceptRequestUser("testtoken", -2,serviceLocator)
+ })
+ expect(error.code).toBe(400)
+ expect(mockUserRepository.getByUser).toHaveBeenCalledTimes(1)
+ })
+
+ it('should throw error 403 friendship doesn\'t exist', async () => {
+ mockFriendRepository.accept = jest.fn((id, id_ami)=> {
+ return null
+ })
+ const error = await catchError(async ()=>{
+ await acceptRequestUser("testtoken", 3,serviceLocator)
+ })
+ expect(error.code).toBe(403)
+ expect(mockUserRepository.getByUser).toHaveBeenCalledTimes(2)
+ expect(mockFriendRepository.accept).toHaveBeenCalledTimes(1)
+ })
+
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/friend/followUser.test.js b/test/unit/application/usecase/friend/followUser.test.js
new file mode 100644
index 0000000..85847fe
--- /dev/null
+++ b/test/unit/application/usecase/friend/followUser.test.js
@@ -0,0 +1,92 @@
+const followUser = require('../../../../../lib/application/use_cases/friend/followUser')
+const catchError = require("../utils/catchError")
+const mockFriendRepository = {}
+const mockUserRepository = {}
+const mockMailRepository = {}
+const mockAccesTokenManager = {}
+
+mockAccesTokenManager.generate = ((test) =>{return ''})
+const relation = {
+ id_utilisateur: 1,
+ amiIdUtilisateur: 2,
+ en_attente: true,
+ createdAt: undefined,
+ updatedAt: undefined,
+ type : 'amis'
+}
+const user = {
+ id_utilisateur : 1,
+ pseudo : "pseudo",
+ email : "test@test.fr",
+ alias : undefined,
+ photo : undefined,
+ photo_temporaire : undefined,
+ token : undefined,
+ refresh_token : undefined,
+ reset_token : undefined,
+ password : "hjkklllllm",
+ id_role : 1,
+ ban_until : undefined,
+ confirmed: undefined,
+ confirm_token : undefined,
+ is_private : true ,
+ type : 'user'
+}
+describe("followUser", ()=>{
+ afterEach(()=>{
+ jest.clearAllMocks();
+ })
+ beforeEach(()=>{
+ mockUserRepository.getByUser = jest.fn((id) => {
+ user.id_utilisateur = id
+ return user
+ })
+ mockFriendRepository.persist = jest.fn((friend) => {
+ return friend
+ })
+ mockMailRepository.send = jest.fn(option => null)
+ mockAccesTokenManager.decode = jest.fn((token)=> {return {value: 1}})
+ })
+
+ const serviceLocator = {
+ userRepository: mockUserRepository,
+ mailRepository: mockMailRepository,
+ friendRepository: mockFriendRepository,
+ accessTokenManager:mockAccesTokenManager
+ }
+ it('should return friendship', async () => {
+
+ const res = await followUser("testtoken",2,serviceLocator)
+ expect(res).toEqual(relation)
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockUserRepository.getByUser).toHaveBeenCalledTimes(2)
+ expect(mockFriendRepository.persist).toHaveBeenCalledTimes(1)
+ expect(mockMailRepository.send).toHaveBeenCalledTimes(1)
+ });
+
+ it('should throw error 400 invalid id friend', async () => {
+ mockUserRepository.getByUser = jest.fn((id)=> {
+ if (id != -1) return user
+ return null
+ })
+ const error = await catchError(async ()=>{
+ await followUser("testtoken",-1,serviceLocator)
+ })
+ expect(error.code).toBe(400)
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockUserRepository.getByUser).toHaveBeenCalledTimes(2)
+ });
+
+ it('should throw error 403 friendship exist', async () => {
+ mockFriendRepository.persist = jest.fn((user)=> {
+ return null
+ })
+ const error = await catchError(async ()=>{
+ await followUser("testtoken",2,serviceLocator)
+ })
+ expect(error.code).toBe(403)
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockUserRepository.getByUser).toHaveBeenCalledTimes(2)
+ expect(mockFriendRepository.persist).toHaveBeenCalledTimes(1)
+ });
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/friend/getListFriends.test.js b/test/unit/application/usecase/friend/getListFriends.test.js
new file mode 100644
index 0000000..13f2128
--- /dev/null
+++ b/test/unit/application/usecase/friend/getListFriends.test.js
@@ -0,0 +1,102 @@
+const getListFriends = require('../../../../../lib/application/use_cases/friend/getListFriends')
+const catchError = require("../utils/catchError")
+const mockFriendRepository = {}
+const mockUserRepository = {}
+const mockAccesTokenManager = {}
+
+mockAccesTokenManager.generate = ((test) =>{return ''})
+const friends = [
+ {
+ id_utilisateur : 1,
+ pseudo : "pseudo",
+ email : "test@test.fr",
+ alias : undefined,
+ photo : undefined,
+ photo_temporaire : undefined,
+ token : undefined,
+ refresh_token : undefined,
+ reset_token : undefined,
+ password : "hjkklllllm",
+ id_role : 1,
+ ban_until : undefined,
+ confirmed: undefined,
+ confirm_token : undefined,
+ is_private : true ,
+ type : 'user'
+ },{
+ id_utilisateur : 2,
+ pseudo : "pseudotest",
+ email : "test@test.fr",
+ alias : undefined,
+ photo : undefined,
+ photo_temporaire : undefined,
+ token : undefined,
+ refresh_token : undefined,
+ reset_token : undefined,
+ password : "hjkklllllm",
+ id_role : 1,
+ ban_until : undefined,
+ confirmed: undefined,
+ confirm_token : undefined,
+ is_private : true ,
+ type : 'user'
+ }
+]
+const user = {
+ id_utilisateur : 3,
+ pseudo : "pseudo",
+ email : "test@test.fr",
+ alias : undefined,
+ photo : undefined,
+ photo_temporaire : undefined,
+ token : undefined,
+ refresh_token : undefined,
+ reset_token : undefined,
+ password : "hjkklllllm",
+ id_role : 1,
+ ban_until : undefined,
+ confirmed: undefined,
+ confirm_token : undefined,
+ is_private : true ,
+ type : 'user'
+}
+describe("getListFriends", ()=>{
+ afterEach(()=>{
+ jest.clearAllMocks();
+ })
+ beforeEach(()=>{
+ mockUserRepository.getByUser = jest.fn((id => user))
+ mockFriendRepository.getListFriendsById = jest.fn((user) => {
+ return friends
+ })
+ mockAccesTokenManager.decode = jest.fn((token)=> {return {value: 1}})
+ })
+
+ const serviceLocator = {
+ userRepository: mockUserRepository,
+ friendRepository: mockFriendRepository,
+ accessTokenManager:mockAccesTokenManager
+ }
+ it('should return list friends of a user', async () => {
+
+ const user = await getListFriends("testtoken",serviceLocator)
+ expect(user).toBe(friends)
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockUserRepository.getByUser).toHaveBeenCalledTimes(1)
+ expect(mockFriendRepository.getListFriendsById).toHaveBeenCalledTimes(1)
+ });
+
+ it('should throw error 400 invalid token user', async () => {
+ mockAccesTokenManager.decode = jest.fn((token)=> {return {value: -1}})
+ mockUserRepository.getByUser = jest.fn((id)=> {
+ return null
+ })
+ const error = await catchError(async ()=>{
+ await getListFriends("testtoken", serviceLocator)
+ })
+ expect(error.code).toBe(400)
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockUserRepository.getByUser).toHaveBeenCalledTimes(1)
+ });
+
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/friend/getListFriendsRequest.test.js b/test/unit/application/usecase/friend/getListFriendsRequest.test.js
new file mode 100644
index 0000000..9622cb6
--- /dev/null
+++ b/test/unit/application/usecase/friend/getListFriendsRequest.test.js
@@ -0,0 +1,86 @@
+const getListFriendsRequest = require('../../../../../lib/application/use_cases/friend/getListFriendsRequest')
+const catchError = require("../utils/catchError")
+const mockFriendRepository = {}
+const mockUserRepository = {}
+const mockAccesTokenManager = {}
+
+mockAccesTokenManager.generate = ((test) =>{return ''})
+const friends = [
+ {
+ id_utilisateur : 4,
+ pseudo : "pseudo",
+ email : "test@test.fr",
+ alias : undefined,
+ photo : undefined,
+ photo_temporaire : undefined,
+ token : undefined,
+ refresh_token : undefined,
+ reset_token : undefined,
+ password : "hjkklllllm",
+ id_role : 1,
+ ban_until : undefined,
+ confirmed: undefined,
+ confirm_token : undefined,
+ is_private : true ,
+ type : 'user'
+ }
+]
+const user = {
+ id_utilisateur : 3,
+ pseudo : "pseudo",
+ email : "test@test.fr",
+ alias : undefined,
+ photo : undefined,
+ photo_temporaire : undefined,
+ token : undefined,
+ refresh_token : undefined,
+ reset_token : undefined,
+ password : "hjkklllllm",
+ id_role : 1,
+ ban_until : undefined,
+ confirmed: undefined,
+ confirm_token : undefined,
+ is_private : true ,
+ type : 'user'
+}
+describe("getListFriendsRequest", ()=>{
+ afterEach(()=>{
+ jest.clearAllMocks();
+ })
+ beforeEach(()=>{
+ mockUserRepository.getByUser = jest.fn((id => user))
+ mockFriendRepository.getRequestFriendsById = jest.fn((id) => {
+ return friends
+ })
+ mockAccesTokenManager.decode = jest.fn((token)=> {return {value: 1}})
+
+ })
+
+ const serviceLocator = {
+ userRepository: mockUserRepository,
+ friendRepository: mockFriendRepository,
+ accessTokenManager: mockAccesTokenManager
+ }
+ it('should return request friends of a user', async () => {
+ const users = await getListFriendsRequest("testtoken",serviceLocator)
+ expect(users).toBe(friends)
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockUserRepository.getByUser).toHaveBeenCalledTimes(1)
+ expect(mockFriendRepository.getRequestFriendsById).toHaveBeenCalledTimes(1)
+ });
+
+ it('should throw error 400 invalid token user', async () => {
+ mockAccesTokenManager.decode = jest.fn((token)=> {return {value: -1}})
+ mockUserRepository.getByUser = jest.fn((id)=> {
+ return null
+ })
+ const error = await catchError(async ()=>{
+ await getListFriendsRequest("testtoken", serviceLocator)
+ })
+ expect(error.code).toBe(400)
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockUserRepository.getByUser).toHaveBeenCalledTimes(1)
+ expect(mockFriendRepository.getRequestFriendsById).toHaveBeenCalledTimes(0)
+ });
+
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/friend/getProfilFriend.test.js b/test/unit/application/usecase/friend/getProfilFriend.test.js
new file mode 100644
index 0000000..88eb50a
--- /dev/null
+++ b/test/unit/application/usecase/friend/getProfilFriend.test.js
@@ -0,0 +1,108 @@
+const getProfilFriend = require('../../../../../lib/application/use_cases/friend/getProfilFriend')
+const catchError = require("../utils/catchError")
+const mockFriendRepository = {}
+const mockUserRepository = {}
+const mockAccesTokenManager = {}
+
+mockAccesTokenManager.generate = ((test) =>{return ''})
+const relation = {
+ id_utilisateur: 1,
+ amiIdUtilisateur: 2,
+ en_attente: true,
+ createdAt: undefined,
+ updatedAt: undefined,
+ type : 'amis'
+}
+const user = {
+ id_utilisateur : 1,
+ pseudo : "pseudo",
+ email : "test@test.fr",
+ alias : undefined,
+ photo : undefined,
+ photo_temporaire : undefined,
+ token : undefined,
+ refresh_token : undefined,
+ reset_token : undefined,
+ password : "hjkklllllm",
+ id_role : 1,
+ ban_until : undefined,
+ confirmed: undefined,
+ confirm_token : undefined,
+ is_private : true ,
+ type : 'user'
+}
+
+const friend = {
+ id_utilisateur : 2,
+ pseudo : "pseudo22",
+ email : "test@test.fr",
+ alias : undefined,
+ photo : undefined,
+ photo_temporaire : undefined,
+ token : undefined,
+ refresh_token : undefined,
+ reset_token : undefined,
+ password : "hjkklllllm",
+ id_role : 1,
+ ban_until : undefined,
+ confirmed: undefined,
+ confirm_token : undefined,
+ is_private : true ,
+ type : 'user'
+}
+
+describe("getProfilFriend", ()=>{
+ afterEach(()=>{
+ jest.clearAllMocks();
+ })
+
+ beforeEach(()=>{
+ mockUserRepository.getByUser = jest.fn((id)=> {
+ return user.id_utilisateur == id ? user : friend
+ })
+ mockFriendRepository.getById = jest.fn((id, id_ami) => {
+ return relation
+ })
+ mockAccesTokenManager.decode = jest.fn((token)=> {return {value: 1}})
+ })
+ const serviceLocator = {
+ userRepository: mockUserRepository,
+ friendRepository: mockFriendRepository,
+ accessTokenManager: mockAccesTokenManager
+ }
+ it('should accept a request friend of a user', async () => {
+
+ const res = await getProfilFriend("testtoken",2,serviceLocator)
+ expect(res).toBe(friend)
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockUserRepository.getByUser).toHaveBeenCalledTimes(2)
+ expect(mockFriendRepository.getById).toHaveBeenCalledTimes(1)
+ });
+
+ it('should throw error 400 invalid id friend', async () => {
+ mockUserRepository.getByUser = jest.fn((id)=> {
+ return null
+ })
+ const error = await catchError(async ()=>{
+ await getProfilFriend("testtoken", -2,serviceLocator)
+ })
+ expect(error.code).toBe(400)
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockUserRepository.getByUser).toHaveBeenCalledTimes(1)
+ expect(mockFriendRepository.getById).toHaveBeenCalledTimes(0)
+ })
+
+ it('should throw error 403 friendship doesn\'t exist', async () => {
+ mockFriendRepository.getById = jest.fn((id, id_ami)=> {
+ return null
+ })
+ const error = await catchError(async ()=>{
+ await getProfilFriend("testtoken", 3,serviceLocator)
+ })
+ expect(error.code).toBe(403)
+ expect(mockUserRepository.getByUser).toHaveBeenCalledTimes(2)
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockFriendRepository.getById).toHaveBeenCalledTimes(1)
+ })
+
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/friend/unfollowUser.test.js b/test/unit/application/usecase/friend/unfollowUser.test.js
new file mode 100644
index 0000000..3d2fd0d
--- /dev/null
+++ b/test/unit/application/usecase/friend/unfollowUser.test.js
@@ -0,0 +1,78 @@
+const unfollowUser = require('../../../../../lib/application/use_cases/friend/unfollowUser')
+const catchError = require("../utils/catchError")
+const mockFriendRepository = {}
+const mockUserRepository = {}
+const mockAccesTokenManager = {}
+
+mockAccesTokenManager.generate = ((test) =>{return ''})
+const relation = {
+ id_utilisateur: undefined,
+ amiIdUtilisateur: undefined,
+ en_attente: false,
+ createdAt: undefined,
+ updatedAt: undefined,
+ type : 'amis'
+}
+const user = {
+ id_utilisateur : 1,
+ pseudo : "pseudo",
+ email : "test@test.fr",
+ alias : undefined,
+ photo : undefined,
+ photo_temporaire : undefined,
+ token : undefined,
+ refresh_token : undefined,
+ reset_token : undefined,
+ password : "hjkklllllm",
+ id_role : 1,
+ ban_until : undefined,
+ confirmed: undefined,
+ confirm_token : undefined,
+ is_private : true ,
+ type : 'user'
+}
+describe("unfollowUser", ()=>{
+ afterEach(()=>{
+ jest.clearAllMocks();
+ })
+ beforeEach(()=>{
+ mockUserRepository.getByUser = jest.fn((id)=> {
+ user.id_utilisateur=id
+ return user
+ })
+ mockFriendRepository.removeFriendById = jest.fn((id, id_ami) => {
+ relation.id_utilisateur = id
+ relation.amiIdUtilisateur = id_ami
+ return relation
+ })
+ mockAccesTokenManager.decode = jest.fn((token)=> {return {value: 1}})
+ })
+
+ const serviceLocator = {
+ userRepository: mockUserRepository,
+ friendRepository: mockFriendRepository,
+ accessTokenManager:mockAccesTokenManager
+ }
+ it('should remove a friend of a user', async () => {
+ const user = await unfollowUser("testtoken",2,serviceLocator)
+ expect(user).toBe(relation)
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockUserRepository.getByUser).toHaveBeenCalledTimes(2)
+ expect(mockFriendRepository.removeFriendById).toHaveBeenCalledTimes(1)
+ });
+
+ it('should throw error 400 invalid id friend', async () => {
+ mockUserRepository.getByUser = jest.fn((id)=> {
+ if (id < 0) return user
+ return null
+ })
+ const error = await catchError(async ()=>{
+ await unfollowUser("testtoken",-2,serviceLocator)
+ })
+ expect(error.code).toBe(400)
+ expect(mockAccesTokenManager.decode).toHaveBeenCalledTimes(1)
+ expect(mockUserRepository.getByUser).toHaveBeenCalledTimes(1)
+ });
+
+
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/oeuvre/getOeuvre.test.js b/test/unit/application/usecase/oeuvre/getOeuvre.test.js
new file mode 100644
index 0000000..a29be6d
--- /dev/null
+++ b/test/unit/application/usecase/oeuvre/getOeuvre.test.js
@@ -0,0 +1,148 @@
+const getOeuvre = require("./../../../../../lib/application/use_cases/oeuvre/getOeuvre")
+const catchError = require("../utils/catchError")
+const {
+ mockUser,
+ mockArtist,
+ mockUserPrivate,
+ mockAlbumRaw,
+ mockLikedReview,
+ mockCommentedReview,
+ mockOeuvreReviewSpotify,
+ expectedArtist
+} = require('../fixtures/getOeuvreFixture')
+
+describe("getOeuvre Test", ()=>{
+ const mockReviewRepository = {}
+ const mockAccesTokenManager = {}
+ const mockUserRepository = {}
+ const mockSpotifyRepository = {}
+ //const mockFollowRepository = {}
+ const mocklikeOeuvreRepository = {}
+ const mockoeuvreFavRepository = {}
+
+ const serviceLocator = {
+ reviewRepository: mockReviewRepository,
+ accessTokenManager: mockAccesTokenManager,
+ userRepository: mockUserRepository,
+ spotifyRepository: mockSpotifyRepository,
+ //followRepository: mockFollowRepository,
+ likeOeuvreRepository : mocklikeOeuvreRepository,
+ oeuvreFavRepository : mockoeuvreFavRepository
+ }
+ describe("valid cases", ()=>{
+ it("should return valid oeuvre with 1 artist", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((idUtilisateur) => mockUser)
+ // mockFollowRepository.getFollowersCount = jest.fn((artistId) => 100)
+ // mockFollowRepository.getFriendsFollowing = jest.fn((artistId,userId,limit) => [mockUserPrivate])
+ // mockFollowRepository.getFriendsFollowingCount = jest.fn((artistId,userId) => 1)
+ mockSpotifyRepository.getSpotifyAlbums = jest.fn((idOeuvre) => {
+ return Promise.resolve(mockAlbumRaw);
+ });
+ mockSpotifyRepository.getSpotifyTracks = jest.fn((idOeuvre));
+ mockSpotifyRepository.getSpotifyArtist = jest.fn((idArtist) => mockArtist);
+
+ mocklikeOeuvreRepository.doesUserLikes = jest.fn((idUtilisateur,idOeuvre)).mockReturnValue(false)
+ mockoeuvreFavRepository.oeuvreFavExists = jest.fn((idUtilisateur,idOeuvre)).mockReturnValue(false)
+
+ mocklikeOeuvreRepository.getLikeCount = jest.fn((idOeuvre) => 9)
+ mockReviewRepository.getReviewCount = jest.fn((idOeuvre) => 2)
+ mockReviewRepository.getOeuvreRating = jest.fn(() => 1)
+ mockReviewRepository.getOeuvreReviews = jest.fn().mockReturnValueOnce([mockLikedReview]).mockReturnValueOnce([mockCommentedReview])
+ mockreviewRepository.doesUserLikes = jest.fn().mockReturnValue(false)
+ mockSpotifyRepository.getOeuvre = jest.fn().mockReturnValue(mockOeuvreReviewSpotify)
+
+ //mockSpotifyRepository.getSpotifyArtist = jest.fn((artistId) => mockArtist)
+ // mockSpotifyRepository.getSpotifyArtistSongs = jest.fn((artistId,filter,limit) => mockAlbumRaw)
+ // mockReviewRepository.getOeuvreRating = jest.fn((id) => 1)
+ //mockReviewRepository.getReviewCount = jest.fn((id) => 2)
+ //mockReviewRepository.getOeuvreReviews = jest.fn().mockReturnValueOnce([mockLikedReview]).mockReturnValueOnce([mockCommentedReview])
+ // mockreviewRepository.doesUserLikes = jest.fn().mockReturnValue(true)
+ // mockFollowRepository.doesFollows = jest.fn().mockReturnValue(true)
+ // mockSpotifyRepository.getOeuvre = jest.fn().mockReturnValue(mockOeuvreReviewSpotify)
+ const result = await getOeuvre(1,'token', serviceLocator)
+ result.albums[0].popularity = 64
+ expect(result).toEqual(expectedOeuvre)
+ })
+ })
+ describe("invalid cases", ()=>{
+ it("should throw error bad auth token", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((id) => null)
+ const error = await catchError(async ()=>{
+ await getArtist(1,'token', serviceLocator)
+ })
+ expect(error.code).toBe(401)
+ })
+ it("should throw error artist not found", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((id) => mockUser)
+ mockSpotifyRepository.getSpotifyArtist = jest.fn((artistId) => {
+ return {
+ error: {
+ status: 400,
+ message: "message",
+ }
+ }
+ })
+ const error = await catchError(async ()=>{
+ await getArtist(1,'token', serviceLocator)
+ })
+ expect(error.code).toBe(400)
+ })
+
+ it("should throw error oeuvre not found 1", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((id) => mockUser)
+ mockFollowRepository.getFollowersCount = jest.fn((artistId) => 100)
+ mockFollowRepository.getFriendsFollowing = jest.fn((artistId,userId,limit) => [mockUserPrivate])
+ mockFollowRepository.getFriendsFollowingCount = jest.fn((artistId,userId) => 1)
+ mockSpotifyRepository.getSpotifyArtist = jest.fn((artistId) => mockArtist)
+ mockSpotifyRepository.getSpotifyArtistSongs = jest.fn((artistId,filter,limit) => mockAlbumRaw)
+ mockReviewRepository.getOeuvreRating = jest.fn((id) => 1)
+ mockReviewRepository.getReviewCount = jest.fn((id) => 2)
+ mockReviewRepository.getOeuvreReviews = jest.fn().mockReturnValueOnce([mockLikedReview]).mockReturnValueOnce([mockCommentedReview])
+ mockreviewRepository.doesUserLikes = jest.fn().mockReturnValue(true)
+ mockFollowRepository.doesFollows = jest.fn().mockReturnValue(true)
+ mockSpotifyRepository.getOeuvre = jest.fn().mockReturnValue({
+ error: {
+ status: 400,
+ message: "message",
+ }
+ })
+
+ const error = await catchError(async ()=>{
+ await getArtist(1,'token', serviceLocator)
+ })
+ expect(error.code).toBe(400)
+ })
+
+ it("should throw error oeuvre not found 2", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((id) => mockUser)
+ mockFollowRepository.getFollowersCount = jest.fn((artistId) => 100)
+ mockFollowRepository.getFriendsFollowing = jest.fn((artistId,userId,limit) => [mockUserPrivate])
+ mockFollowRepository.getFriendsFollowingCount = jest.fn((artistId,userId) => 1)
+ mockSpotifyRepository.getSpotifyArtist = jest.fn((artistId) => mockArtist)
+ mockSpotifyRepository.getSpotifyArtistSongs = jest.fn((artistId,filter,limit) => mockAlbumRaw)
+ mockReviewRepository.getOeuvreRating = jest.fn((id) => 1)
+ mockReviewRepository.getReviewCount = jest.fn((id) => 2)
+ mockReviewRepository.getOeuvreReviews = jest.fn().mockReturnValueOnce([mockLikedReview]).mockReturnValueOnce([mockCommentedReview])
+ mockreviewRepository.doesUserLikes = jest.fn().mockReturnValue(true)
+ mockFollowRepository.doesFollows = jest.fn().mockReturnValue(true)
+ mockSpotifyRepository.getOeuvre = jest.fn().mockReturnValueOnce(mockOeuvreReviewSpotify).mockReturnValue({
+ error: {
+ status: 400,
+ message: "message",
+ }
+ })
+
+ const error = await catchError(async ()=>{
+ await getArtist(1,'token', serviceLocator)
+ })
+ expect(error.code).toBe(400)
+ })
+
+ })
+
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/oeuvre/likeOeuvre.test.js b/test/unit/application/usecase/oeuvre/likeOeuvre.test.js
new file mode 100644
index 0000000..70980ee
--- /dev/null
+++ b/test/unit/application/usecase/oeuvre/likeOeuvre.test.js
@@ -0,0 +1,91 @@
+const catchError = require("../utils/catchError")
+const likeOeuvre = require("../../../../../lib/application/use_cases/oeuvre/likeOeuvre")
+const mockUserRepository = {}
+const mockLikeOeuvreRepository = {}
+const mockAccessTokenManager = {}
+const mockSpotifyRepository = {}
+
+const serviceLocator = {
+ userRepository: mockUserRepository,
+ likeOeuvreRepository: mockLikeOeuvreRepository,
+ accessTokenManager: mockAccessTokenManager,
+ spotifyRepository: mockSpotifyRepository
+}
+
+describe("like oeuvre use case ", ()=>{
+ const mockUser = {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+ }
+ const mockArtist = {
+ external_urls: { spotify: 'https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN' },
+ genres: [ 'french hip hop', 'old school rap francais', 'rap conscient' ],
+ id: '4FpJcNgOvIpSBeJgRg3OfN',
+ images: [
+ {
+ height: 640,
+ url: 'https://i.scdn.co/image/ab6761610000e5eb32086a424e6f1e499e347cde',
+ width: 640
+ },
+ ],
+ name: 'Orelsan',
+ popularity: 64,
+ type: 'artist',
+ }
+ const errror = {
+ error: {
+ status: 400,
+ message: "message",
+ }
+ }
+ describe("valid usecase", ()=>{
+
+ it("should return true", async ()=>{
+ mockAccessTokenManager.decode = jest.fn(()=>{return {value:1}})
+ mockUserRepository.getByUser = jest.fn().mockReturnValue(mockUser)
+ mockSpotifyRepository.getOeuvre = jest.fn().mockReturnValue(mockArtist)
+ mockLikeOeuvreRepository.doesUserLike = jest.fn().mockReturnValue(false)
+ mockLikeOeuvreRepository.like = jest.fn()
+ const result = await likeOeuvre(1,1,"artist",serviceLocator)
+ expect(result).toBe(true)
+ })
+
+ it("should return false", async ()=>{
+ mockAccessTokenManager.decode = jest.fn(()=>{return {value:1}})
+ mockUserRepository.getByUser = jest.fn().mockReturnValue(mockUser)
+ mockSpotifyRepository.getOeuvre = jest.fn().mockReturnValue(mockArtist)
+ mockLikeOeuvreRepository.doesUserLike = jest.fn().mockReturnValue(true)
+ mockLikeOeuvreRepository.unlike = jest.fn()
+ const result = await likeOeuvre(1,1,"artist",serviceLocator)
+ expect(result).toBe(false)
+ })
+ })
+
+ describe("invalid usecase", ()=>{
+ it("should return error 401", async ()=>{
+ mockAccessTokenManager.decode = jest.fn(()=>{return {value:1}})
+ mockUserRepository.getByUser = jest.fn().mockReturnValue(null)
+ const error = await catchError(async ()=>{
+ await likeOeuvre(1,1,"artist", serviceLocator)
+ })
+ expect(error.code).toBe(401)
+ })
+ it("should return error 400", async ()=>{
+ mockAccessTokenManager.decode = jest.fn(()=>{return {value:1}})
+ mockUserRepository.getByUser = jest.fn().mockReturnValue(mockUser)
+ mockSpotifyRepository.getOeuvre = jest.fn().mockReturnValue(errror)
+ const error = await catchError(async ()=>{
+ await likeOeuvre(1,1,"artist", serviceLocator)
+ })
+ expect(error.code).toBe(400)
+ })
+ })
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/review/deleteReview.test.js b/test/unit/application/usecase/review/deleteReview.test.js
new file mode 100644
index 0000000..dbf513e
--- /dev/null
+++ b/test/unit/application/usecase/review/deleteReview.test.js
@@ -0,0 +1,50 @@
+const deleteReview = require("./../../../../../lib/application/use_cases/review/deleteReview")
+const catchError = require("../utils/catchError")
+describe("deleteReview Test", ()=>{
+ const mockReviewRepository = {}
+ const mockAccesTokenManager = {}
+ const mockUserRepository = {}
+ const serviceLocator = {
+ reviewRepository: mockReviewRepository,
+ accessTokenManager: mockAccesTokenManager,
+ userRepository: mockUserRepository,
+ }
+ describe("valid cases", ()=>{
+ it("should delete review", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((id) => {
+ return {
+ id_utilisateur: 1
+ }
+ })
+ mockReviewRepository.delete = jest.fn((id) => true)
+ await deleteReview(1,'token', serviceLocator)
+ expect(mockReviewRepository.delete).toHaveBeenCalledTimes(1)
+ })
+ })
+ describe("invalid cases", ()=>{
+ it("should throw error bad auth token", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((id) => null)
+ const error = await catchError(async ()=>{
+ await deleteReview(1,'token', serviceLocator)
+ })
+ expect(error.code).toBe(401)
+ })
+ it("should throw error not post owner", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((id) => {
+ return {
+ id_utilisateur: 1
+ }
+ })
+ mockReviewRepository.delete = jest.fn((id) => false)
+ const error = await catchError(async ()=>{
+ await deleteReview(1,'token', serviceLocator)
+ })
+ expect(error.code).toBe(403)
+ })
+
+ })
+
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/review/fixture/getOeuvreReviewsFixture.js b/test/unit/application/usecase/review/fixture/getOeuvreReviewsFixture.js
new file mode 100644
index 0000000..bc561c6
--- /dev/null
+++ b/test/unit/application/usecase/review/fixture/getOeuvreReviewsFixture.js
@@ -0,0 +1,80 @@
+const mockArtist = {
+ id: "32kWZXLpwGm5Y2B0lKb6Ii",
+ name: "Bob Marley",
+ images: [{
+ height: 640,
+ url: "https://i.scdn.co/image/ab67616d0000b273c9adfbd773852e286faed040",
+ width: 640
+ }],
+ external_urls: {spotify: "https://open.spotify.com/artist/32kWZXLpwGm5Y2B0lKb6Ii"},
+ popularity: 79,
+ genres: ["Reggae", "Roots"]
+}
+const mockUser = {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+}
+const mockPublicUser = {
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_utilisateur: 1,
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+}
+
+const actualDate = new Date()
+const rawReview = {
+ id_review: 1,
+ id_oeuvre: 1,
+ countlike: 2,
+ countComment: 4,
+ description: "C'est top",
+ note: 5,
+ createdAt: actualDate,
+ updated_at: actualDate,
+ type: 'artist',
+ utilisateur: mockUser
+}
+const expectedReview = {
+ id_review:1,
+ description: "C'est top",
+ countlike: 2,
+ countComment: 4,
+ note: 5,
+ createdAt: actualDate,
+ doesUserLike: false,
+ oeuvre: {
+ id: "32kWZXLpwGm5Y2B0lKb6Ii",
+ name: "Bob Marley",
+ image: "https://i.scdn.co/image/ab67616d0000b273c9adfbd773852e286faed040",
+ spotify_url: "https://open.spotify.com/artist/32kWZXLpwGm5Y2B0lKb6Ii",
+ popularity: 79,
+ genres: ["Reggae", "Roots"],
+ type: "artist"
+ },
+ utilisateur: mockPublicUser,
+ type: 'artist',
+}
+
+
+
+
+
+module.exports = {
+ mockArtist,
+ rawReview,
+ expectedReview,
+}
\ No newline at end of file
diff --git a/test/unit/application/usecase/review/fixture/getReviewFixture.js b/test/unit/application/usecase/review/fixture/getReviewFixture.js
new file mode 100644
index 0000000..74dccab
--- /dev/null
+++ b/test/unit/application/usecase/review/fixture/getReviewFixture.js
@@ -0,0 +1,138 @@
+const mockArtist = {
+ id: "32kWZXLpwGm5Y2B0lKb6Ii",
+ name: "Bob Marley",
+ images: [{
+ height: 640,
+ url: "https://i.scdn.co/image/ab67616d0000b273c9adfbd773852e286faed040",
+ width: 640
+ }],
+ external_urls: {spotify: "https://open.spotify.com/artist/32kWZXLpwGm5Y2B0lKb6Ii"},
+ popularity: 79,
+ genres: ["Reggae", "Roots"]
+}
+const mockUser = {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+}
+
+
+const mockPublicUser = {
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_utilisateur: 1,
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+}
+const mockComments = [
+ {
+ id: 298,
+ description: 'test4',
+ utilisateur: mockPublicUser
+ }
+ ]
+const mockUserPrivate = {
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ id_utilisateur: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: true
+}
+const actualDate = new Date()
+const rawReview = {
+ id_review: 1,
+ id_oeuvre: 1,
+ countlike: 2,
+ countComment: 4,
+ description: "C'est top",
+ note: 5,
+ createdAt: actualDate,
+ updated_at: actualDate,
+ type: 'artist',
+ utilisateur: mockUser
+}
+const expectedReview = {
+ id_review:1,
+ description: "C'est top",
+ countlike: 2,
+ countComment: 4,
+ note: 5,
+ createdAt: actualDate,
+ doesUserLike: false,
+ oeuvre: {
+ id: "32kWZXLpwGm5Y2B0lKb6Ii",
+ name: "Bob Marley",
+ image: "https://i.scdn.co/image/ab67616d0000b273c9adfbd773852e286faed040",
+ spotify_url: "https://open.spotify.com/artist/32kWZXLpwGm5Y2B0lKb6Ii",
+ popularity: 79,
+ genres: ["Reggae", "Roots"],
+ type: "artist"
+ },
+ comments: mockComments,
+ utilisateur: mockPublicUser,
+ type: 'artist',
+}
+
+
+
+const rawReviewPrivate = {
+ id_review: 1,
+ id_oeuvre: 1,
+ countlike: 2,
+ countComment: 4,
+ description: "C'est top",
+ note: 5,
+ createdAt: actualDate,
+ updated_at: actualDate,
+ type: 'artist',
+ utilisateur: mockUserPrivate
+}
+const expectedPrivate = {
+ id_review:1,
+ description: "C'est top",
+ countlike: 2,
+ countComment: 4,
+ note: 5,
+ createdAt: actualDate,
+ doesUserLike: false,
+ oeuvre: {
+ id: "32kWZXLpwGm5Y2B0lKb6Ii",
+ name: "Bob Marley",
+ image: "https://i.scdn.co/image/ab67616d0000b273c9adfbd773852e286faed040",
+ spotify_url: "https://open.spotify.com/artist/32kWZXLpwGm5Y2B0lKb6Ii",
+ popularity: 79,
+ genres: ["Reggae", "Roots"],
+ type: "artist"
+ },
+ comments: mockComments,
+ utilisateur: mockUserPrivate,
+ type: 'artist',
+}
+
+
+module.exports = {
+ rawReview,
+ mockArtist,
+ expectedReview,
+ rawReviewPrivate,
+ expectedPrivate,
+ mockComments,
+
+}
\ No newline at end of file
diff --git a/test/unit/application/usecase/review/fixture/getReviewLikesFixture.js b/test/unit/application/usecase/review/fixture/getReviewLikesFixture.js
new file mode 100644
index 0000000..a3566da
--- /dev/null
+++ b/test/unit/application/usecase/review/fixture/getReviewLikesFixture.js
@@ -0,0 +1,29 @@
+const mockUser = {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+
+}
+const mockPublicUser = {
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ id_utilisateur: 1,
+ email: "testemail@gmail",
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+}
+module.exports = {
+ mockUser,
+ mockPublicUser
+}
\ No newline at end of file
diff --git a/test/unit/application/usecase/review/fixture/getReviewsFixture.js b/test/unit/application/usecase/review/fixture/getReviewsFixture.js
new file mode 100644
index 0000000..ea1e698
--- /dev/null
+++ b/test/unit/application/usecase/review/fixture/getReviewsFixture.js
@@ -0,0 +1,76 @@
+const mockArtist = {
+ id: "32kWZXLpwGm5Y2B0lKb6Ii",
+ name: "Bob Marley",
+ images: [{
+ height: 640,
+ url: "https://i.scdn.co/image/ab67616d0000b273c9adfbd773852e286faed040",
+ width: 640
+ }],
+ external_urls: {spotify: "https://open.spotify.com/artist/32kWZXLpwGm5Y2B0lKb6Ii"},
+ popularity: 79,
+ genres: ["Reggae", "Roots"]
+}
+const mockUser = {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+}
+const actualDate = new Date()
+const rawReview = {
+ id_review: 1,
+ id_oeuvre: 1,
+ countlike: 2,
+ countComment: 4,
+ description: "C'est top",
+ note: 5,
+ createdAt: actualDate,
+ updatedAt: actualDate,
+ type: 'artist',
+ utilisateur: mockUser
+}
+const mockPublicUser = {
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_utilisateur: 1,
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+}
+const expectedReview = {
+ id_review:1,
+ description: "C'est top",
+ countlike: 2,
+ countComment: 4,
+ note: 5,
+ createdAt: actualDate,
+ doesUserLike: false,
+ oeuvre: {
+ id: "32kWZXLpwGm5Y2B0lKb6Ii",
+ name: "Bob Marley",
+ image: "https://i.scdn.co/image/ab67616d0000b273c9adfbd773852e286faed040",
+ spotify_url: "https://open.spotify.com/artist/32kWZXLpwGm5Y2B0lKb6Ii",
+ popularity: 79,
+ genres: ["Reggae", "Roots"],
+ type: "artist"
+ },
+ utilisateur: mockPublicUser,
+ type: 'artist',
+}
+
+
+module.exports = {
+ rawReview,
+ mockArtist,
+ expectedReview,
+}
\ No newline at end of file
diff --git a/test/unit/application/usecase/review/fixture/getUserReviewFixture.js b/test/unit/application/usecase/review/fixture/getUserReviewFixture.js
new file mode 100644
index 0000000..8cb6d92
--- /dev/null
+++ b/test/unit/application/usecase/review/fixture/getUserReviewFixture.js
@@ -0,0 +1,95 @@
+const mockArtist = {
+ id: "32kWZXLpwGm5Y2B0lKb6Ii",
+ name: "Bob Marley",
+ images: [{
+ height: 640,
+ url: "https://i.scdn.co/image/ab67616d0000b273c9adfbd773852e286faed040",
+ width: 640
+ }],
+ external_urls: {spotify: "https://open.spotify.com/artist/32kWZXLpwGm5Y2B0lKb6Ii"},
+ popularity: 79,
+ genres: ["Reggae", "Roots"]
+}
+const mockUser = {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+}
+
+
+const mockPublicUser = {
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_utilisateur: 1,
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+}
+
+const mockUserPrivate = {
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ id_utilisateur: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: true
+}
+const actualDate = new Date()
+const rawReview = {
+ id_review: 1,
+ id_oeuvre: 1,
+ countlike: 2,
+ countComment: 4,
+ description: "C'est top",
+ note: 5,
+ createdAt: actualDate,
+ updatedAt: actualDate,
+ type: 'artist',
+ utilisateur: mockUser
+}
+const expectedReview = {
+ id_review:1,
+ description: "C'est top",
+ countlike: 2,
+ countComment: 4,
+ note: 5,
+ createdAt: actualDate,
+ doesUserLike: false,
+ oeuvre: {
+ id: "32kWZXLpwGm5Y2B0lKb6Ii",
+ name: "Bob Marley",
+ image: "https://i.scdn.co/image/ab67616d0000b273c9adfbd773852e286faed040",
+ spotify_url: "https://open.spotify.com/artist/32kWZXLpwGm5Y2B0lKb6Ii",
+ popularity: 79,
+ genres: ["Reggae", "Roots"],
+ type: "artist"
+ },
+ utilisateur: mockPublicUser,
+ type: 'artist',
+}
+
+
+
+
+
+module.exports = {
+ rawReview,
+ mockArtist,
+ expectedReview,
+
+}
\ No newline at end of file
diff --git a/test/unit/application/usecase/review/fixture/putReviewFixture.js b/test/unit/application/usecase/review/fixture/putReviewFixture.js
new file mode 100644
index 0000000..a2da09b
--- /dev/null
+++ b/test/unit/application/usecase/review/fixture/putReviewFixture.js
@@ -0,0 +1,90 @@
+const mockArtist = {
+ id: "32kWZXLpwGm5Y2B0lKb6Ii",
+ name: "Bob Marley",
+ images: [{
+ height: 640,
+ url: "https://i.scdn.co/image/ab67616d0000b273c9adfbd773852e286faed040",
+ width: 640
+ }],
+ external_urls: {spotify: "https://open.spotify.com/artist/32kWZXLpwGm5Y2B0lKb6Ii"},
+ popularity: 79,
+ genres: ["Reggae", "Roots"]
+}
+const mockUser = {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+
+}
+const mockPublicUser = {
+ pseudo: "John Doe",
+ id_utilisateur:1,
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: false
+}
+const mockUserPrivate = {
+ pseudo: "John Doe",
+ alias: "John",
+ ban_until: null,
+ email: "testemail@gmail",
+ id_role: 1,
+ photo: null,
+ photo_temporaire: null,
+ type: "user",
+ is_private: true
+}
+const actualDate = new Date()
+const rawReview = {
+ id_review: 1,
+ id_oeuvre: 1,
+ countlike: 2,
+ countComment: 4,
+ description: "C'est top",
+ note: 5,
+ createdAt: actualDate,
+ updated_at: actualDate,
+ type: 'artist',
+ utilisateur: mockUser
+}
+const expectedReview = {
+ id_review:1,
+ description: "C'est top",
+ countlike: 2,
+ countComment: 4,
+ note: 5,
+ createdAt: actualDate,
+ doesUserLike: false,
+ oeuvre: {
+ id: "32kWZXLpwGm5Y2B0lKb6Ii",
+ name: "Bob Marley",
+ image: "https://i.scdn.co/image/ab67616d0000b273c9adfbd773852e286faed040",
+ spotify_url: "https://open.spotify.com/artist/32kWZXLpwGm5Y2B0lKb6Ii",
+ popularity: 79,
+ genres: ["Reggae", "Roots"],
+ type: "artist"
+ },
+ utilisateur: mockPublicUser,
+ type: 'artist',
+}
+
+
+
+
+module.exports = {
+ rawReview,
+ mockArtist,
+ expectedReview
+}
\ No newline at end of file
diff --git a/test/unit/application/usecase/review/getOeuvreReviews.test.js b/test/unit/application/usecase/review/getOeuvreReviews.test.js
new file mode 100644
index 0000000..3346f7c
--- /dev/null
+++ b/test/unit/application/usecase/review/getOeuvreReviews.test.js
@@ -0,0 +1,59 @@
+const getOeuvreReviews = require("../../../../../lib/application/use_cases/review/getOeuvreReviews")
+const catchError = require("../utils/catchError")
+const {
+ mockArtist,
+ rawReview,
+ expectedReview,
+} = require("./fixture/getOeuvreReviewsFixture")
+
+describe("getReviews Test", ()=>{
+ const mockReviewRepository = {}
+ const mockAccesTokenManager = {}
+ const mockSpotifyRepository = {}
+ const serviceLocator = {
+ reviewRepository: mockReviewRepository,
+ accessTokenManager: mockAccesTokenManager,
+ spotifyRepository: mockSpotifyRepository,
+ }
+ describe("valid cases", ()=>{
+ it("should return serialized review with public user", async ()=>{
+ mockReviewRepository.getOeuvreReviews = jest.fn((id_utilisateur,page,pageSize,orderByLike) => [rawReview])
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => mockArtist)
+ const expectedReviews = [expectedReview]
+ const result = await getOeuvreReviews(1,undefined,1,10,true, serviceLocator)
+ expect(result).toEqual(expectedReviews)
+ })
+ it("should return serialized review with private user", async ()=>{
+
+ mockAccesTokenManager.decode = jest.fn((userToken) => {
+ return {value: 1}
+ })
+ mockReviewRepository.getOeuvreReviews = jest.fn((id_utilisateur,page,pageSize,orderByLike) => [rawReview])
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => mockArtist)
+ mockreviewRepository.doesUserLikes = jest.fn((id_utilisateur,reviewId) => false)
+ const expectedReviews = [expectedReview]
+ const result = await getOeuvreReviews(1,'token',1,10,true, serviceLocator)
+ expect(result).toEqual(expectedReviews)
+ })
+ })
+
+ describe("invalide cases", ()=>{
+ it("should throw error 400", async ()=>{
+ mockReviewRepository.getOeuvreReviews = jest.fn((id_utilisateur,page,pageSize,orderByLike) => [rawReview])
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => {
+ return {
+ error: {
+ status: 400,
+ message: "message",
+ }
+ }
+ })
+ const error = await catchError(async () => {
+ await getOeuvreReviews(1,undefined,1,10,true, serviceLocator)
+ })
+ expect(error.code).toBe(400)
+ })
+
+ })
+
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/review/getReview.test.js b/test/unit/application/usecase/review/getReview.test.js
new file mode 100644
index 0000000..54ef6f9
--- /dev/null
+++ b/test/unit/application/usecase/review/getReview.test.js
@@ -0,0 +1,107 @@
+const getReview = require("../../../../../lib/application/use_cases/review/getReview")
+const catchError = require("../utils/catchError")
+
+const {
+ mockArtist,
+ rawReview,
+ expectedReview,
+ rawReviewPrivate,
+ expectedPrivate,
+ mockComments
+} = require("./fixture/getReviewFixture")
+
+
+describe("getReview Test", ()=>{
+ const mockReviewRepository = {}
+ const mockFriendRepository = {}
+ const mockAccesTokenManager = {}
+ const mockSpotifyRepository = {}
+ const mockCommentRepository = {}
+ const serviceLocator = {
+ reviewRepository: mockReviewRepository,
+ friendRepository: mockFriendRepository,
+ accessTokenManager: mockAccesTokenManager,
+ spotifyRepository: mockSpotifyRepository,
+ commentRepository: mockCommentRepository
+ }
+
+ describe("successful cases", () => {
+ it("should return review with artist from repository", async () => {
+ mockReviewRepository.getById = jest.fn((id) => rawReview)
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => mockArtist)
+ mockCommentRepository.getReviewComments = jest.fn().mockReturnValue(mockComments)
+ const result = await getReview(1,undefined,1,10,true, serviceLocator)
+ console.log(result)
+ expect(result).toEqual(expectedReview)
+ })
+ it("should return review with artist private from repository", async () => {
+ mockReviewRepository.getById = jest.fn((id) => rawReviewPrivate)
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => mockArtist)
+ mockFriendRepository.areFriends = jest.fn((id, id_ami) => true)
+ mockAccesTokenManager.decode = jest.fn((token) => {return {value: 1}})
+ mockreviewRepository.doesUserLikes = jest.fn((id_utilisateur,reviewId) => false)
+ const result = await getReview(1,'something',1,10,true, serviceLocator)
+ expect(result).toEqual(expectedPrivate)
+ })
+
+ })
+ describe("invalid cases", () => {
+ it("should throw review not found error", async () => {
+ mockReviewRepository.getById = jest.fn((id) => null)
+ const error = await catchError(async () => {
+ await getReview(1,undefined,1,10,true, serviceLocator)
+ })
+ console.log(error)
+ expect(error.code).toBe(404)
+ })
+ it("should throw user private 1", async () => {
+ const mockReview = {
+ utilisateur: {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ is_private: true
+ }
+ }
+ mockReviewRepository.getById = jest.fn((id) => mockReview)
+ const error = await catchError(async () => {
+ await getReview(1,undefined,1,10,true, serviceLocator)
+ })
+ expect(error.code).toBe(403)
+ })
+
+ it("should throw user private 2", async () => {
+ const mockReview = {
+ utilisateur: {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ is_private: true
+ }
+ }
+ mockReviewRepository.getById = jest.fn((id) => mockReview)
+ mockFriendRepository.areFriends = jest.fn((id, id_ami) => false)
+ mockAccesTokenManager.decode = jest.fn((token) => {return {value: 1}})
+ const error = await catchError(async () => {
+ await getReview(1,'something',1,10,true, serviceLocator)
+ })
+ expect(error.code).toBe(403)
+ expect(mockFriendRepository.areFriends).toHaveBeenCalledTimes(1)
+ expect().hasBee
+ })
+ it("should throw error review not found ", async () => {
+ mockReviewRepository.getById = jest.fn((id) => rawReview)
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => {
+ return {
+ error: {
+ status: 400,
+ message: "message",
+ }
+ }
+ })
+ const error = await catchError(async () => {
+ await getReview(1,undefined,1,10,true, serviceLocator)
+ })
+ expect(error.code).toBe(400)
+
+ })
+ })
+})
diff --git a/test/unit/application/usecase/review/getReviewLikes.test.js b/test/unit/application/usecase/review/getReviewLikes.test.js
new file mode 100644
index 0000000..8804049
--- /dev/null
+++ b/test/unit/application/usecase/review/getReviewLikes.test.js
@@ -0,0 +1,88 @@
+const getReviewLikes = require("./../../../../../lib/application/use_cases/review/getReviewLikes")
+const catchError = require("../utils/catchError")
+const {
+ mockUser,
+ mockPublicUser
+} = require("./fixture/getReviewLikesFixture")
+describe("getReviewLikes Test", ()=>{
+ const mockReviewRepository = {}
+ const mockAccesTokenManager = {}
+ const mockUserRepository = {}
+ const mockFriendRepository = {}
+ const serviceLocator = {
+ reviewRepository: mockReviewRepository,
+ accessTokenManager: mockAccesTokenManager,
+ userRepository: mockUserRepository,
+ friendRepository: mockFriendRepository
+ }
+ describe("invalid cases", ()=>{
+
+ it("should throw review not found error", async ()=>{
+ mockReviewRepository.getById = jest.fn((id) => null)
+ const error = await catchError(async ()=>{
+ await getReviewLikes(1,'token',1,10, serviceLocator)
+ })
+ expect(error.code).toBe(404)
+ })
+ it("should throw user is private error 1", async ()=>{
+ const mockReview = {
+ utilisateur: {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ is_private: true
+ }
+ }
+ mockReviewRepository.getById = jest.fn((id) => mockReview)
+ mockAccesTokenManager.decode = jest.fn((token) => {return {value: 1}})
+ mockFriendRepository.areFriends = jest.fn((id, id_ami) => false)
+ const error = await catchError(async ()=>{
+ await getReviewLikes(1,'token',1,10, serviceLocator)
+ })
+ expect(error.code).toBe(403)
+ })
+ it("should throw user is private error 2", async ()=>{
+ const mockReview = {
+ utilisateur: {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ is_private: true
+ }
+ }
+ mockReviewRepository.getById = jest.fn((id) => mockReview)
+ const error = await catchError(async ()=>{
+ await getReviewLikes(1,undefined,1,10, serviceLocator)
+ })
+ expect(error.code).toBe(403)
+ })
+ })
+ describe("valid cases", ()=>{
+ it("should get review private like", async ()=>{
+ const mockReview = {
+ utilisateur: {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ is_private: true
+ }
+ }
+ mockReviewRepository.getById = jest.fn((id) => mockReview)
+ mockAccesTokenManager.decode = jest.fn((token) => {return {value: 1}})
+ mockFriendRepository.areFriends = jest.fn((id, id_ami) => true)
+ mockReviewRepository.getLikes = jest.fn((id) => [mockUser])
+ const result = await getReviewLikes(1,'token',1,10, serviceLocator)
+ expect(result).toEqual([mockPublicUser])
+ })
+ it("should get review public", async ()=>{
+ const mockReview = {
+ utilisateur: {
+ id_utilisateur: 1,
+ pseudo: "John Doe",
+ is_private: false
+ }
+ }
+ mockReviewRepository.getById = jest.fn((id) => mockReview)
+ mockReviewRepository.getLikes = jest.fn((id) => [mockUser])
+ const result = await getReviewLikes(1,undefined,1,10, serviceLocator)
+ expect(result).toEqual([mockPublicUser])
+ })
+ })
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/review/getReviews.test.js b/test/unit/application/usecase/review/getReviews.test.js
new file mode 100644
index 0000000..32c9cdb
--- /dev/null
+++ b/test/unit/application/usecase/review/getReviews.test.js
@@ -0,0 +1,37 @@
+const getReviews = require("../../../../../lib/application/use_cases/review/getReviews")
+
+const {
+ mockArtist,
+ rawReview,
+ expectedReview,
+} = require("./fixture/getReviewsFixture")
+
+describe("getReviews Test", ()=>{
+ const mockReviewRepository = {}
+ const mockAccesTokenManager = {}
+ const mockSpotifyRepository = {}
+ const serviceLocator = {
+ reviewRepository: mockReviewRepository,
+ accessTokenManager: mockAccesTokenManager,
+ spotifyRepository: mockSpotifyRepository,
+ }
+ it("should return serialized review", async ()=>{
+
+ mockReviewRepository.getReviews = jest.fn((page,pageSize,orderByLike, isPrivate,userToken) => [rawReview])
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => mockArtist)
+ mockreviewRepository.doesUserLikes = jest.fn((id_utilisateur,reviewId) => false)
+ const expectedReviews = [expectedReview]
+ const result = await getReviews(1,10,true,undefined, serviceLocator)
+ expect(result).toEqual(expectedReviews)
+ })
+
+ it("should return serialized review with user login", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((token) => {return {value: 1}})
+ mockReviewRepository.getReviews = jest.fn((page,pageSize,orderByLike, isPrivate,userToken) => [rawReview])
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => mockArtist)
+ mockreviewRepository.doesUserLikes = jest.fn((id_utilisateur,reviewId) => false)
+ const expectedReviews = [expectedReview]
+ const result = await getReviews(1,10,true,'something', serviceLocator)
+ expect(result).toEqual(expectedReviews)
+ })
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/review/getUserReviews.test.js b/test/unit/application/usecase/review/getUserReviews.test.js
new file mode 100644
index 0000000..2bf786a
--- /dev/null
+++ b/test/unit/application/usecase/review/getUserReviews.test.js
@@ -0,0 +1,95 @@
+const getUserReviews = require("../../../../../lib/application/use_cases/review/getUserReviews")
+const catchError = require("../utils/catchError")
+const {
+ mockArtist,
+ rawReview,
+ expectedReview,
+} = require("./fixture/getUserReviewFixture")
+
+describe("getReviews Test", ()=>{
+ const mockReviewRepository = {}
+ const mockAccesTokenManager = {}
+ const mockSpotifyRepository = {}
+ const mockUserRepository = {}
+ const mockFriendRepository = {}
+ const serviceLocator = {
+ reviewRepository: mockReviewRepository,
+ accessTokenManager: mockAccesTokenManager,
+ spotifyRepository: mockSpotifyRepository,
+ userRepository: mockUserRepository,
+ friendRepository: mockFriendRepository,
+ }
+ describe("successful cases", ()=>{
+ it("should return serialized review with public user", async ()=>{
+ mockUserRepository.getByEmailOrPseudo = jest.fn((pseudo,email) => {
+ return {
+ id_utilisateur: 1,
+ is_private: false
+ }
+ })
+ mockReviewRepository.getReviewByUserId = jest.fn((id_utilisateur,page,pageSize,orderByLike) => [rawReview])
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => mockArtist)
+ const expectedReviews = [expectedReview]
+ const result = await getUserReviews(1,'token',1,10,true, serviceLocator)
+ expect(result).toEqual(expectedReviews)
+ })
+ it("should return serialized review with private user", async ()=>{
+ mockUserRepository.getByEmailOrPseudo = jest.fn((pseudo,email) => {
+ return {
+ id_utilisateur: 1,
+ is_private: true
+ }
+ })
+ mockAccesTokenManager.decode = jest.fn((userToken) => {
+ return {value: 1}
+ })
+ mockFriendRepository.areFriends = jest.fn((id, id_ami) => true)
+ mockReviewRepository.getReviewByUserId = jest.fn((id_utilisateur,page,pageSize,orderByLike) => [rawReview])
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => mockArtist)
+ mockreviewRepository.doesUserLikes = jest.fn((id_utilisateur,reviewId) => false)
+ const expectedReviews = [expectedReview]
+ const result = await getUserReviews(1,'token',1,10,true, serviceLocator)
+ expect(result).toEqual(expectedReviews)
+ })
+ })
+ describe("invalid cases", ()=>{
+
+ it("should throw error user private 1", async ()=>{
+ mockUserRepository.getByEmailOrPseudo = jest.fn((pseudo,email) => {
+ return {
+ id_utilisateur: 1,
+ is_private: true
+ }
+ })
+ const error = await catchError(async ()=>{
+ await getUserReviews(1,undefined,1,10,true, serviceLocator)
+ })
+ expect(error.code).toBe(403)
+ })
+
+ it("should throw error user dont exist", async ()=>{
+ mockUserRepository.getByEmailOrPseudo = jest.fn().mockReturnValue(null)
+ const error = await catchError(async ()=>{
+ await getUserReviews(1,undefined,1,10,true, serviceLocator)
+ })
+ expect(error.code).toBe(404)
+ })
+ it("should throw error user private 2", async ()=>{
+ mockUserRepository.getByEmailOrPseudo = jest.fn((pseudo,email) => {
+ return {
+ id_utilisateur: 1,
+ is_private: true
+ }
+ })
+ mockAccesTokenManager.decode = jest.fn((userToken) => {
+ return {value: 1}
+ })
+ mockFriendRepository.areFriends = jest.fn((id, id_ami) => false)
+ const error = await catchError(async ()=>{
+ await getUserReviews(1,'token',1,10,true, serviceLocator)
+ })
+ expect(error.code).toBe(403)
+ expect(mockFriendRepository.areFriends).toHaveBeenCalledTimes(1)
+ })
+ })
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/review/likeReview.test.js b/test/unit/application/usecase/review/likeReview.test.js
new file mode 100644
index 0000000..ce3f64e
--- /dev/null
+++ b/test/unit/application/usecase/review/likeReview.test.js
@@ -0,0 +1,50 @@
+const likeReview = require("../../../../../lib/application/use_cases/review/likeReview")
+const catchError = require("../utils/catchError")
+describe("likeReview Test", ()=>{
+ const mockReviewRepository = {}
+ const mockAccesTokenManager = {}
+ const mockUserRepository = {}
+
+
+ const serviceLocator = {
+ reviewRepository: mockReviewRepository,
+ accessTokenManager: mockAccesTokenManager,
+ userRepository: mockUserRepository,
+ }
+ describe("valid cases", ()=>{
+ it("should like review", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => {return {value: 1}})
+ mockUserRepository.getByUser = jest.fn((id) => {
+ return {
+ id_utilisateur: 1
+ }
+ })
+ mockreviewRepository.doesUserLikes = jest.fn((id) => true)
+ mockReviewRepository.unlikeReview = jest.fn((id) => true)
+ await likeReview(1,'token', serviceLocator)
+ expect(mockReviewRepository.unlikeReview).toHaveBeenCalledTimes(1)
+ })
+
+ it("should unlike review", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => {return {value: 1}})
+ mockUserRepository.getByUser = jest.fn((id) => {
+ return {
+ id_utilisateur: 1
+ }
+ })
+ mockreviewRepository.doesUserLikes = jest.fn((id) => false)
+ mockReviewRepository.likeReview = jest.fn((id) => true)
+ await likeReview(1,'token', serviceLocator)
+ expect(mockReviewRepository.likeReview).toHaveBeenCalledTimes(1)
+ })
+ })
+ describe("invalid cases", ()=>{
+ it("should throw error bad auth token", async ()=>{
+ mockUserRepository.getByUser = jest.fn((id) => null)
+ const error = await catchError(async ()=>{
+ await await likeReview(1,'token', serviceLocator)
+ })
+ expect(error.code).toBe(401)
+ })
+ })
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/review/putReview.test.js b/test/unit/application/usecase/review/putReview.test.js
new file mode 100644
index 0000000..a24fd26
--- /dev/null
+++ b/test/unit/application/usecase/review/putReview.test.js
@@ -0,0 +1,108 @@
+const putReview = require("../../../../../lib/application/use_cases/review/putReview")
+const catchError = require("../utils/catchError")
+describe("putReview Test", ()=>{
+ const idOeuvre = 'idOeuvre'
+ const userToken = 'token'
+ const description = 'description'
+ const note = 5
+ const type = 'artist'
+ const {
+ rawReview,
+ mockArtist,
+ expectedReview,
+ } = require("./fixture/putReviewFixture")
+ const mockReviewRepository = {}
+ const mockAccesTokenManager = {}
+ const mockSpotifyRepository = {}
+ const mockUserRepository = {}
+ const serviceLocator = {
+ reviewRepository: mockReviewRepository,
+ accessTokenManager: mockAccesTokenManager,
+ spotifyRepository: mockSpotifyRepository,
+ userRepository: mockUserRepository,
+ }
+ describe("invalid cases", ()=>{
+
+ it("should throw error bad auth token", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((userToken) => null)
+ const error = await catchError(async ()=>{
+ await putReview(idOeuvre, userToken, description,note, type, serviceLocator)
+ })
+ expect(error.code).toBe(401)
+ })
+ it("should throw error review already posted", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((userToken) => {
+ return {
+ id_utilisateur: 1
+ }
+ })
+ mockReviewRepository.getByUserAndId = jest.fn((idOeuvre, id_utilisateur) => {
+ return {
+ id_review: 1
+ }
+ })
+
+ const error = await catchError(async ()=>{
+ await putReview(idOeuvre, userToken, description,note, type, serviceLocator)
+ })
+ expect(error.code).toBe(403)
+ })
+ it("should throw error type review doesn't exist", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((userToken) => {
+ return {
+ id_utilisateur: 1
+ }
+ })
+ mockReviewRepository.getByUserAndId = jest.fn((idOeuvre, id_utilisateur) => null)
+ mockReviewRepository.getTypeReviewID = jest.fn((type) => null)
+ const error = await catchError(async ()=>{
+ await putReview(idOeuvre, userToken, description,note, type, serviceLocator)
+ })
+ expect(error.code).toBe(404)
+ expect(mockReviewRepository.getTypeReviewID).toHaveBeenCalledTimes(1)
+ })
+ it("should throw error rawOeuvre ", async ()=>{
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((userToken) => {
+ return {
+ id_utilisateur: 1
+ }
+ })
+ mockReviewRepository.getByUserAndId = jest.fn((idOeuvre, id_utilisateur) => null)
+ mockReviewRepository.getTypeReviewID = jest.fn((type) => 1)
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => {
+ return {
+ error: {
+ status: 400,
+ message: 'error'
+ }
+ }
+ })
+ const error = await catchError(async ()=>{
+ await putReview(idOeuvre, userToken, description,note, type, serviceLocator)
+ })
+ expect(error.code).toBe(400)
+ })
+ })
+ describe("valid cases", ()=>{
+
+ it("should put review", async ()=>{
+ mockUserRepository.getByUser = jest.fn((userToken) => {
+ return {
+ id_utilisateur: 1
+ }
+ })
+ mockReviewRepository.getByUserAndId = jest.fn((idOeuvre, id_utilisateur) => null)
+ mockReviewRepository.getTypeReviewID = jest.fn((type) => 1)
+ mockReviewRepository.persist = jest.fn((reviewRaw) => rawReview)
+ mockSpotifyRepository.getOeuvre = jest.fn((id,type) => mockArtist)
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ const result = await putReview(idOeuvre, userToken, description,note, type, serviceLocator)
+ expect(result).toEqual(expectedReview)
+ })
+
+ })
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/spotify/FetchArtist.test.js b/test/unit/application/usecase/spotify/FetchArtist.test.js
new file mode 100644
index 0000000..6099c08
--- /dev/null
+++ b/test/unit/application/usecase/spotify/FetchArtist.test.js
@@ -0,0 +1,39 @@
+const fetchArtist = require("../../../../../lib/application/use_cases/spotify/FetchArtist")
+const catchError = require("../utils/catchError")
+const {
+ artistFixture, // reponse pas serialise
+ expectedFixture, // reponse serialise
+} = require("../fixtures/fetchArtist")
+
+const mockSpotifyRepository = {}
+
+
+const idOrelsan = "4FpJcNgOvIpSBeJgRg3OfN"
+
+describe('FetchArtist usecase', () => {
+ it("should return a serialized artist item", async ()=>{
+ mockSpotifyRepository.getSpotifyArtist = jest.fn((id) =>{
+ return artistFixture
+ })
+ const result = await fetchArtist( // fetchArtist metier, serialize est fait a la fin
+ idOrelsan,
+ {spotifyRepository : mockSpotifyRepository}) // va utiliser la fct getSpotifyArtist de mockSpotifyRepository
+ console.log("result", result)
+ console.log("expectedFixture", expectedFixture)
+
+ expect(result).toEqual(expectedFixture)
+ expect(mockSpotifyRepository.getSpotifyArtist).toHaveBeenCalledWith(idOrelsan)
+ })
+ it("should return throw an error 400", async ()=>{
+ mockSpotifyRepository.getSpotifyArtist = jest.fn((id) =>{
+ throw new Error('test error')
+ })
+ const error = await catchError(async ()=> {
+ await fetchArtist( // fetchArtist metier, serialize est fait a la fin
+ idOrelsan,
+ {spotifyRepository : mockSpotifyRepository}) // va utiliser la fct getSpotifyArtist de mockSpotifyRepository
+
+ })
+ expect(error.code).toBe(400)
+ })
+});
\ No newline at end of file
diff --git a/test/unit/application/usecase/spotify/FetchArtistSongs.test.js b/test/unit/application/usecase/spotify/FetchArtistSongs.test.js
new file mode 100644
index 0000000..f642d82
--- /dev/null
+++ b/test/unit/application/usecase/spotify/FetchArtistSongs.test.js
@@ -0,0 +1,146 @@
+const { VERSION } = require("underscore");
+const catchError = require("../utils/catchError")
+
+const FetchArtistSongs = require("../../../../../lib/application/use_cases/spotify/FetchArtistSongs")
+const {
+ songsRawAlbumArtist,
+ expectedAlbumArtist,
+ songsRawSingleArtist,
+ expectedSingleArtist,
+ songsRawCompilationArtist,
+ expectedCompilationArtist,
+ songsRawAppearsOnArtist,
+ expectedAppearsOnArtist
+} = require("../../../interfaces/serializers/fixtures/artistAlbumsFixture")
+
+const songsRawAll = {
+ items: [
+ songsRawAlbumArtist.items[0],
+ songsRawSingleArtist.items[0],
+ songsRawCompilationArtist.items[0],
+ songsRawAppearsOnArtist.items[0]
+ ],
+ }
+
+ const expectedFixturesAll = [
+ expectedAlbumArtist[0],
+ expectedSingleArtist[0],
+ expectedCompilationArtist[0],
+ expectedAppearsOnArtist[0]
+ ];
+
+ const songsRawAlbumSingle = {
+ items: [
+ songsRawAlbumArtist.items[0],
+ songsRawSingleArtist.items[0]
+ ]
+ }
+
+ const expectedFixturesAlbumSingle = [
+ expectedAlbumArtist[0],
+ expectedSingleArtist[0]
+ ];
+
+
+const mockSpotifyRepository = {}
+
+const id = "57TzZhbqvYoUBzJSVKFVlG"
+const album ="album"
+const single ="single"
+const compilation ="compilation"
+const appearsOn = "appears_on"
+
+
+describe('FetchArtistSongs usecase', () => {
+ it("should return a serialized album item", async ()=>{
+ mockSpotifyRepository.getSpotifyArtistSongs = jest.fn((id, filter, limit) =>{
+ return songsRawAlbumArtist
+ })
+ const result = await FetchArtistSongs( // fetchArtist metier, serialize est fait a la fin
+ id,
+ album,
+ 1,
+ {spotifyRepository : mockSpotifyRepository}) // va utiliser la fct getSpotifyArtistSongs de mockSpotifyRepository
+ expect(result).toEqual(expectedAlbumArtist)
+ expect(mockSpotifyRepository.getSpotifyArtistSongs).toHaveBeenCalledWith(id, album, 1)
+
+ })
+
+ it("should return a serialized album type single item", async ()=>{
+ mockSpotifyRepository.getSpotifyArtistSongs = jest.fn((id, filter, limit) =>{
+ return songsRawSingleArtist
+ })
+ const result = await FetchArtistSongs( // fetchArtist metier, serialize est fait a la fin
+ id,
+ single,
+ 1,
+ {spotifyRepository : mockSpotifyRepository}) // va utiliser la fct getSpotifyArtistSongs de mockSpotifyRepository
+ expect(result).toEqual(expectedSingleArtist)
+ expect(mockSpotifyRepository.getSpotifyArtistSongs).toHaveBeenCalledWith(id, single, 1)
+ })
+
+
+
+ it("should return a serialized album type compilation item", async ()=>{
+ mockSpotifyRepository.getSpotifyArtistSongs = jest.fn((id, filter, limit) =>{
+ return songsRawCompilationArtist
+ })
+ const result = await FetchArtistSongs( // fetchArtist metier, serialize est fait a la fin
+ id,
+ compilation,
+ 1,
+ {spotifyRepository : mockSpotifyRepository}) // va utiliser la fct getSpotifyArtistSongs de mockSpotifyRepository
+ expect(result).toEqual(expectedCompilationArtist)
+ expect(mockSpotifyRepository.getSpotifyArtistSongs).toHaveBeenCalledWith(id, compilation, 1)
+ })
+
+ it("should return a serialized album type appears_on item", async ()=>{
+ mockSpotifyRepository.getSpotifyArtistSongs = jest.fn((id, filter, limit) =>{
+ return songsRawAppearsOnArtist
+ })
+ const result = await FetchArtistSongs( // fetchArtist metier, serialize est fait a la fin
+ id,
+ appearsOn,
+ 1,
+ {spotifyRepository : mockSpotifyRepository}) // va utiliser la fct getSpotifyArtistSongs de mockSpotifyRepository
+ expect(result).toEqual(expectedAppearsOnArtist)
+ expect(mockSpotifyRepository.getSpotifyArtistSongs).toHaveBeenCalledWith(id, appearsOn, 1)
+ })
+
+ it("should return 4 serialized album's type album, single, compilation and appears_on items", async ()=>{
+ mockSpotifyRepository.getSpotifyArtistSongs = jest.fn((id, filter, limit) =>{
+ return songsRawAll
+ })
+ const result = await FetchArtistSongs( // fetchArtist metier, serialize est fait a la fin
+ id,
+ "album,single,compilation,appears_on",
+ 4,
+ {spotifyRepository : mockSpotifyRepository}) // va utiliser la fct getSpotifyArtistSongs de mockSpotifyRepository
+ expect(result).toEqual(expectedFixturesAll)
+ expect(mockSpotifyRepository.getSpotifyArtistSongs).toHaveBeenCalledWith(id, "album,single,compilation,appears_on" , 4)
+ })
+
+ it("should return 2 serialized album's type album and single", async ()=>{
+ mockSpotifyRepository.getSpotifyArtistSongs = jest.fn((id, filter, limit) =>{
+ return songsRawAlbumSingle
+ })
+ const result = await FetchArtistSongs( // fetchArtist metier, serialize est fait a la fin
+ id,
+ "album,single",
+ 2,
+ {spotifyRepository : mockSpotifyRepository}) // va utiliser la fct getSpotifyArtistSongs de mockSpotifyRepository
+ expect(result).toEqual(expectedFixturesAlbumSingle)
+ expect(mockSpotifyRepository.getSpotifyArtistSongs).toHaveBeenCalledWith(id,"album,single" , 2)
+ })
+
+ it("should return throw an error 400", async ()=>{
+ mockSpotifyRepository.getSpotifyArtistSongs = jest.fn((id, filter, limit) =>{
+ throw new Error('test error')
+ })
+
+ const error = await catchError(async ()=> {
+ await FetchArtistSongs(id, "single", 1, {spotifyRepository : mockSpotifyRepository})
+ })
+ expect(error.code).toBe(400)
+ })
+});
\ No newline at end of file
diff --git a/test/unit/application/usecase/spotify/GetToken.test.js b/test/unit/application/usecase/spotify/GetToken.test.js
new file mode 100644
index 0000000..16bf5d3
--- /dev/null
+++ b/test/unit/application/usecase/spotify/GetToken.test.js
@@ -0,0 +1,29 @@
+const getToken = require("../../../../../lib/application/use_cases/spotify/GetToken")
+const catchError = require("../utils/catchError")
+const mockSpotifyRepository = {}
+
+describe("GetToken", () =>{
+ describe("GetToken valid ", ()=>{
+
+ it("should return valid json", async ()=>{
+ const expectedSpotifyCode = {
+ access_token: "access_token",
+ refresh_token: "refresh_token",
+ }
+ mockSpotifyRepository.getToken = jest.fn((code )=> {return expectedSpotifyCode})
+ const result = await getToken("code",{spotifyRepository: mockSpotifyRepository})
+ })
+ })
+ describe("GetToken invalid ", ()=>{
+ it("should return error", async ()=>{
+ const expectedSpotifyCode = {
+ error: "something"
+ }
+ mockSpotifyRepository.getToken = jest.fn((code )=> {return expectedSpotifyCode})
+ const error = await catchError(async ()=>{
+ await getToken("code",{spotifyRepository: mockSpotifyRepository})
+ })
+ expect(error.code).toBe(400)
+ })
+ })
+})
diff --git a/test/unit/application/usecase/spotify/Search.test.js b/test/unit/application/usecase/spotify/Search.test.js
index 3e6a78c..06b7810 100644
--- a/test/unit/application/usecase/spotify/Search.test.js
+++ b/test/unit/application/usecase/spotify/Search.test.js
@@ -21,7 +21,6 @@ describe('Search usecase', () => {
"test",
"filter",
4,
- false,
{spotifyRepository : mockSpotifyRepository,userRepository: mockUserRepository})
expect(result).toEqual(expectedSearchResult)
expect(mockSpotifyRepository.getSpotifySearchList).toHaveBeenCalledWith("test","filter",4)
@@ -29,12 +28,11 @@ describe('Search usecase', () => {
it("should return item list sorted by popularity with user", async ()=>{
const result = await Search(
"test",
- "filter",
+ "user,track",
4,
- true,
{spotifyRepository : mockSpotifyRepository,userRepository: mockUserRepository})
expect(result).toEqual(expectedSearchResultWithUsers)
- expect(mockSpotifyRepository.getSpotifySearchList).toHaveBeenCalledWith("test","filter",3)
+ expect(mockSpotifyRepository.getSpotifySearchList).toHaveBeenCalledWith("test","track",3)
})
});
//see
\ No newline at end of file
diff --git a/test/unit/application/usecase/spotify/follow.test.js b/test/unit/application/usecase/spotify/follow.test.js
new file mode 100644
index 0000000..f74b00a
--- /dev/null
+++ b/test/unit/application/usecase/spotify/follow.test.js
@@ -0,0 +1,59 @@
+const follow = require("../../../../../lib/application/use_cases/user/follow")
+const mockUserRepository = {}
+const mockAccesTokenManager = {}
+const mockSpotifyRepository = {}
+const mockFollowRepository = {}
+const catchError = require("../utils/catchError")
+const serviceLocator = {
+ userRepository: mockUserRepository,
+ accessTokenManager:mockAccesTokenManager,
+ spotifyRepository: mockSpotifyRepository,
+ followRepository: mockFollowRepository
+}
+describe("follow use case", ()=>{
+ it("should return false",async ()=>{
+ mockAccesTokenManager.decode = jest.fn(()=>{return {id:1}})
+ mockUserRepository.getByUser = jest.fn(() => "something")
+ mockSpotifyRepository.getSpotifyArtist = jest.fn(()=>"something")
+ mockFollowRepository.doesFollows = jest.fn(()=> true)
+ mockFollowRepository.follow = jest.fn(()=> {})
+ mockFollowRepository.unfollow = jest.fn(()=> {})
+ const result = await follow("something","something",serviceLocator)
+ expect(result).toBe(false);
+ })
+ it("should return true",async ()=>{
+ mockAccesTokenManager.decode = jest.fn(()=>{return {id:1}})
+ mockUserRepository.getByUser = jest.fn(() => "something")
+ mockSpotifyRepository.getSpotifyArtist = jest.fn(()=>"something")
+ mockFollowRepository.doesFollows = jest.fn(()=> false)
+ mockFollowRepository.follow = jest.fn(()=> {})
+ mockFollowRepository.unfollow = jest.fn(()=> {})
+ const result = await follow("something","something",serviceLocator)
+ expect(result).toBe(true);
+ })
+ it("should return error code 401",async ()=>{
+ mockAccesTokenManager.decode = jest.fn(()=>{return {id:1}})
+ mockUserRepository.getByUser = jest.fn(() => null)
+
+ const result = await catchError(async ()=>{
+ await follow("something","something",serviceLocator)
+ })
+ expect(result.code).toBe(401);
+ })
+ it("should return return invalid code 415",async ()=>{
+ mockAccesTokenManager.decode = jest.fn(()=>{return {id:1}})
+ mockUserRepository.getByUser = jest.fn(() => "something")
+ mockSpotifyRepository.getSpotifyArtist = jest.fn(()=>{
+ return {
+ error: {
+ status:415,
+ message: "message"
+ }
+ }
+ })
+ const result = await catchError(async ()=>{
+ await follow("something","something",serviceLocator)
+ })
+ expect(result.code).toBe(415);
+ })
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/spotify/getAlbum.test.js b/test/unit/application/usecase/spotify/getAlbum.test.js
new file mode 100644
index 0000000..0516400
--- /dev/null
+++ b/test/unit/application/usecase/spotify/getAlbum.test.js
@@ -0,0 +1,63 @@
+const getAlbum = require("../../../../../lib/application/use_cases/spotify/getAlbum")
+
+const {
+ albumRawOneArtist,
+ expectedAlbumOneArtist,
+ albumRawSeveralArtist,
+ expectedAlbumSeveralArtist,
+ albumRawNoArtist,
+ expectedAlbumNoArtist
+} = require("../../../interfaces/serializers/fixtures/albumTrackFixture")
+const catchError = require("../utils/catchError");
+const mockSpotifyRepository = {}
+
+
+describe('get an album usecase', () => {
+ it("should return an album with one artist 1", async ()=>{
+ mockSpotifyRepository.getSpotifyAlbums = jest.fn((id) =>{
+ return albumRawOneArtist
+ })
+ const result = await getAlbum(
+ "45i3tB9z0dgJ33olyrsLUz",
+ {spotifyRepository : mockSpotifyRepository}
+ )
+ result.popularity = 0
+ expect(result).toEqual(expectedAlbumOneArtist)
+ })
+ it("should return an album with one artist 2", async ()=>{
+ mockSpotifyRepository.getSpotifyAlbums = jest.fn((id) =>{
+ return albumRawSeveralArtist
+ })
+ const result = await getAlbum(
+ "45i3tB9z0dgJ33olyrsLUz",
+ {spotifyRepository : mockSpotifyRepository}
+ )
+ result.popularity = 0
+ expect(result).toEqual(expectedAlbumSeveralArtist)
+ })
+ it("should return an album with one artist 3", async ()=>{
+ mockSpotifyRepository.getSpotifyAlbums = jest.fn((id) =>{
+ return albumRawNoArtist
+ })
+ const result = await getAlbum(
+ "45i3tB9z0dgJ33olyrsLUz",
+ {spotifyRepository : mockSpotifyRepository}
+ )
+ result.popularity = 0
+ expect(result).toEqual(expectedAlbumNoArtist)
+ })
+ it("should throw error", async ()=>{
+ mockSpotifyRepository.getSpotifyAlbums = jest.fn((id) =>{
+ return {error : {status: 400, message: "msg"}}
+ })
+
+ const error = await catchError(async ()=>{
+ await getAlbum(
+ "45i3tB9z0dgJ33olyrsLUz",
+ {spotifyRepository : mockSpotifyRepository}
+ )
+ })
+ expect(error.code).toBe(400)
+ })
+});
+//see
\ No newline at end of file
diff --git a/test/unit/application/usecase/spotify/getSearchFilters.test.js b/test/unit/application/usecase/spotify/getSearchFilters.test.js
new file mode 100644
index 0000000..f537ffa
--- /dev/null
+++ b/test/unit/application/usecase/spotify/getSearchFilters.test.js
@@ -0,0 +1,27 @@
+const getSearchFilters = require("../../../../../lib/application/use_cases/spotify/getSearchFilters")
+
+
+describe('getSearchFilters usecase', () => {
+ it("should return list of filters", async ()=>{
+ const expectSearchFixture = [
+ {
+ label: 'Musique',
+ id: 'track'
+ },
+ {
+ label: 'Artiste',
+ id: 'artist'
+ },
+ {
+ label: 'Album',
+ id: 'album'
+ },
+ {
+ label: 'Utilisateur',
+ id: 'user'
+ },
+ ]
+ const result = getSearchFilters()
+ expect(result).toEqual(expectSearchFixture)
+ })
+});
\ No newline at end of file
diff --git a/test/unit/application/usecase/spotify/getTrack.test.js b/test/unit/application/usecase/spotify/getTrack.test.js
new file mode 100644
index 0000000..63d35cf
--- /dev/null
+++ b/test/unit/application/usecase/spotify/getTrack.test.js
@@ -0,0 +1,80 @@
+const getTrack = require("../../../../../lib/application/use_cases/spotify/getTrack")
+const {
+ expectedRawTrackWithOneArtistOneAlbum,
+ rawTrackWithOneArtistOneAlbum,
+ expectedRawTrackWithServeralArtists,
+ rawTrackWithServeralArtists,
+ expectedRawTrackWithNoArtist,
+ rawTrackWithNoArtist,
+ rawTrackWithNoAlbum,
+ expectedRawTrackWithNoAlbum
+} = require("../../../interfaces/serializers/fixtures/trackFixture")
+const catchError = require("../utils/catchError");
+
+const mockSpotifyRepository = {}
+
+
+describe('get a track usecase', () => {
+ it("should return a track with one artist", async ()=>{
+ mockSpotifyRepository.getSpotifyTracks = jest.fn((id) =>{
+ return rawTrackWithOneArtistOneAlbum
+ })
+
+ const result = await getTrack(
+ "3YP99J8wTzG55t1cFmd6iq",
+ {spotifyRepository : mockSpotifyRepository}
+ )
+ expectedRawTrackWithOneArtistOneAlbum.album.popularity = result.album.popularity
+ expect(result).toEqual(expectedRawTrackWithOneArtistOneAlbum)
+ })
+ it("should return a track with several artists", async ()=>{
+ mockSpotifyRepository.getSpotifyTracks = jest.fn((id) =>{
+ return rawTrackWithServeralArtists
+ })
+
+ const result = await getTrack(
+ "3YP99J8wTzG55t1cFmd6iq",
+ {spotifyRepository : mockSpotifyRepository}
+ )
+ expectedRawTrackWithOneArtistOneAlbum.album.popularity = result.album.popularity
+ expect(result).toEqual(expectedRawTrackWithServeralArtists)
+ })
+ it("should return a track with no artist", async ()=>{
+ mockSpotifyRepository.getSpotifyTracks = jest.fn((id) =>{
+ return rawTrackWithNoArtist
+ })
+
+ const result = await getTrack(
+ "3YP99J8wTzG55t1cFmd6iq",
+ {spotifyRepository : mockSpotifyRepository}
+ )
+ expectedRawTrackWithOneArtistOneAlbum.album.popularity = result.album.popularity
+ expect(result).toEqual(expectedRawTrackWithNoArtist)
+ })
+ it("should return a track with no album", async ()=>{
+ mockSpotifyRepository.getSpotifyTracks = jest.fn((id) =>{
+ return rawTrackWithNoAlbum
+ })
+
+ const result = await getTrack(
+ "3YP99J8wTzG55t1cFmd6iq",
+ {spotifyRepository : mockSpotifyRepository}
+ )
+ expect(result).toEqual(expectedRawTrackWithNoAlbum)
+ })
+ it("should throw error", async ()=>{
+ mockSpotifyRepository.getSpotifyTracks = jest.fn((id) =>{
+ return {error : {status: 400, message: "msg"}}
+ })
+
+ const error = await catchError(async ()=>{
+ await getTrack(
+ "3YP99J8wTzG55t1cFmd6iq",
+ {spotifyRepository : mockSpotifyRepository}
+ )
+ })
+ expect(error.code).toBe(400)
+ })
+});
+
+
diff --git a/test/unit/application/usecase/user/authWithSpotify.test.js b/test/unit/application/usecase/user/authWithSpotify.test.js
new file mode 100644
index 0000000..ba6e673
--- /dev/null
+++ b/test/unit/application/usecase/user/authWithSpotify.test.js
@@ -0,0 +1,138 @@
+const AuthWithSpotify = require('../../../../../lib/application/use_cases/user/AuthWithSpotify')
+const catchError = require("../utils/catchError")
+const mockUserRepository = {}
+const mockSpotifyRepository = {}
+const mockAccessTokenManager = {}
+const serviceLocator = {
+ userRepository: mockUserRepository,
+ spotifyRepository: mockSpotifyRepository,
+ accessTokenManager: mockAccessTokenManager
+}
+describe('AuthWithSpotifyTest', () =>{
+ const mockSpotifyCode = 'code'
+ const email = "some@mail"
+ const display_name = "name"
+ const access_token = 'access_token'
+ const refresh_token = 'refresh_token'
+ const images = ["https://i.ytimg.com/vi/uLHdmBf1lvs/hq720.jpg?sqp=-oaymwEXCNAFEJQDSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLAmH-kUIb43CviOetK-ZjGl0AnSog"]
+ afterEach(()=>{
+ jest.clearAllMocks();
+ })
+ beforeEach(() => {
+ mockUserRepository.updateUser = jest.fn(() => "ok")
+ })
+ it("should throw error 400", async ()=>{
+ mockSpotifyRepository.getToken = jest.fn(()=> {
+ return {error: 'some error'}
+ })
+ const error = await catchError(async () =>{
+ await AuthWithSpotify(mockSpotifyCode, 'callback',serviceLocator)
+ })
+ expect(error.code).toBe(400)
+
+ })
+ it("should throw error 403 1", async ()=>{
+ mockSpotifyRepository.getToken = jest.fn(()=> {
+ return {
+ access_token,
+ refresh_token
+ }
+ })
+ mockSpotifyRepository.getAccountData = jest.fn(()=> {
+ return {email,display_name,images}
+ })
+ mockUserRepository.getByEmailOrPseudo = jest.fn(()=> {
+ return {
+ confirmed: false
+ }
+ })
+ const error = await catchError(async () =>{
+ await AuthWithSpotify(mockSpotifyCode, 'callback',serviceLocator)
+ })
+ expect(error.code).toBe(403)
+ })
+ it("should throw error 403 2", async ()=>{
+ mockSpotifyRepository.getToken = jest.fn(()=> {
+ return {
+ access_token,
+ refresh_token
+ }
+ })
+ mockSpotifyRepository.getAccountData = jest.fn(()=> {
+ return {email,display_name,images}
+ })
+ mockUserRepository.getByEmailOrPseudo = jest.fn(()=> {
+ return {
+ confirmed: true,
+ }
+ })
+ mockAccessTokenManager.generate = jest.fn(() => 'expected_token')
+ const error = await catchError(async () =>{
+ await AuthWithSpotify(mockSpotifyCode, 'callback',serviceLocator)
+ })
+ expect(error.code).toBe(403)
+ })
+ it("should return auth token", async ()=>{
+ mockSpotifyRepository.getToken = jest.fn(()=> {
+ return {
+ access_token,
+ refresh_token
+ }
+ })
+ mockSpotifyRepository.getAccountData = jest.fn(()=> {
+ return {email,display_name,images}
+ })
+ mockUserRepository.getByEmailOrPseudo = jest.fn(()=> {
+ return {
+ confirmed: true,
+ refresh_token: 'something'
+ }
+ })
+ mockAccessTokenManager.generate = jest.fn(() => 'expected_token')
+ const result = await AuthWithSpotify(mockSpotifyCode, 'callback',serviceLocator)
+ expect(result.email).toBe(email)
+ expect(result.token).toBe("expected_token")
+ expect(mockAccessTokenManager.generate).toHaveBeenCalled()
+ })
+ it("should return confirm token 1", async ()=>{
+ mockSpotifyRepository.getToken = jest.fn(()=> {
+ return {
+ access_token,
+ refresh_token
+ }
+ })
+ mockSpotifyRepository.getAccountData = jest.fn(()=> {
+ return {email,display_name,images}
+ })
+ mockUserRepository.getByEmailOrPseudo = jest.fn(()=> {
+ return null
+ })
+ mockUserRepository.persist = jest.fn(() => 'ok')
+ const result = await AuthWithSpotify(mockSpotifyCode, 'callback',serviceLocator)
+ expect(result.confirmToken).not.toBeNull()
+ expect(mockUserRepository.persist).toHaveBeenCalled()
+ })
+ it("should return confirm token 2", async ()=>{
+ mockSpotifyRepository.getToken = jest.fn(()=> {
+ return {
+ access_token,
+ refresh_token
+ }
+ })
+ mockSpotifyRepository.getAccountData = jest.fn(()=> {
+ return {email,display_name,images}
+ })
+ mockUserRepository.getByEmailOrPseudo = jest.fn(()=> {
+ return {
+ auth_with_spotify: true,
+ confirm_token: "expected_token",
+ refresh_token: "something"
+ }
+ })
+ mockUserRepository.persist = jest.fn(() => 'ok')
+ const result = await AuthWithSpotify(mockSpotifyCode, 'callback',serviceLocator)
+ expect(result.confirmToken).toBe("expected_token")
+ expect(mockUserRepository.persist).not.toHaveBeenCalled()
+ })
+
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/user/completeAccount.test.js b/test/unit/application/usecase/user/completeAccount.test.js
new file mode 100644
index 0000000..ea5bcff
--- /dev/null
+++ b/test/unit/application/usecase/user/completeAccount.test.js
@@ -0,0 +1,81 @@
+const completeAccount = require('../../../../../lib/application/use_cases/user/CompleteAccount')
+const catchError = require("../utils/catchError")
+const mockUserRepository = {}
+const mockDocumentRepository = {}
+const mockAccessTokenManager = {}
+const serviceLocator = {
+ userRepository: mockUserRepository,
+ documentRepository: mockDocumentRepository,
+ accessTokenManager: mockAccessTokenManager
+}
+describe('CompleteAccount', () =>{
+ const pseudo= 'testPseudo'
+ const alias= 'testAlias'
+ const bio= 'testBio'
+ const confirm_token= 'confirmToken'
+ const photo = "otherpath/to/file"
+ const email = "testemail@gmail.com"
+ const photo_temporaire = "path/to/file"
+ const confirmed = false
+ const id_utilisateur = 1
+ const mockToken = 'token'
+ const mockUser = {
+ id_utilisateur,email,photo_temporaire,confirmed,confirm_token
+ }
+ mockAccessTokenManager.generate = jest.fn(() => mockToken)
+ mockDocumentRepository.deleteFile = jest.fn(()=>{})
+ mockUserRepository.updateUser = jest.fn((user)=>user)
+ afterEach(()=>{
+ jest.clearAllMocks();
+ })
+ it("should return user with replaced photo ", async ()=>{
+ mockUserRepository.getByEmailOrPseudo = jest.fn(()=>null)
+ mockUserRepository.getByConfirmToken = jest.fn(()=>{
+ return {...mockUser}
+ })
+ const user = await completeAccount(pseudo,alias,bio,photo,confirm_token,serviceLocator)
+ expect(user.token).toBe(mockToken)
+ expect(user.email).toBe(email)
+
+ expect(mockDocumentRepository.deleteFile).toHaveBeenCalledTimes(1)
+ })
+ it("should return user without replaced photo ", async ()=>{
+ mockUserRepository.getByEmailOrPseudo = jest.fn(()=>null)
+ mockUserRepository.getByConfirmToken = jest.fn(()=>{
+ return {...mockUser}
+ })
+ const user = await completeAccount(pseudo,alias,bio,null,confirm_token,serviceLocator)
+ expect(user.token).toBe(mockToken)
+ expect(user.email).toBe(email)
+
+ expect(mockDocumentRepository.deleteFile).toHaveBeenCalledTimes(0)
+ })
+ it("should return user without alias", async ()=>{
+ mockUserRepository.getByEmailOrPseudo = jest.fn(()=>null)
+ mockUserRepository.getByConfirmToken = jest.fn(()=>{
+ return {...mockUser}
+ })
+ const user = await completeAccount(pseudo,null,bio,null,confirm_token,serviceLocator)
+ expect(user.token).toBe(mockToken)
+ expect(user.email).toBe(email)
+
+ })
+ it("should throw error 403 user already exists", async ()=>{
+ mockUserRepository.getByConfirmToken = jest.fn(()=>{
+ return {...mockUser}
+ })
+ mockUserRepository.getByEmailOrPseudo = jest.fn(()=>'something')
+ const error = await catchError(async ()=>{
+ await completeAccount(pseudo,null,bio,null,confirm_token,serviceLocator)
+ })
+ expect(error.code).toBe(403)
+ })
+ it("should throw error 400 invalid token", async ()=>{
+ mockUserRepository.getByConfirmToken = jest.fn(()=>null)
+ mockUserRepository.getByEmailOrPseudo = jest.fn(()=>null)
+ const error = await catchError(async ()=>{
+ await completeAccount(pseudo,null,bio,null,confirm_token,serviceLocator)
+ })
+ expect(error.code).toBe(400)
+ })
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/user/createUser.test.js b/test/unit/application/usecase/user/createUser.test.js
new file mode 100644
index 0000000..a7c0ff9
--- /dev/null
+++ b/test/unit/application/usecase/user/createUser.test.js
@@ -0,0 +1,37 @@
+const createUser = require('../../../../../lib/application/use_cases/user/CreateUser')
+const catchError = require("../utils/catchError")
+const mockUserRepository = {}
+const mockMailRepository = {}
+const email = "testemail@gmail.com"
+const display_name = "display_name"
+const image = [{url:"testurl"}]
+describe("createUser", ()=>{
+ afterEach(()=>{
+ jest.clearAllMocks();
+ })
+ mockUserRepository.getByEmailOrPseudo = jest.fn((email,pseudo)=> null)
+ mockUserRepository.persist = jest.fn((user) => {
+ user.id_utilisateur = 1
+ return user
+ })
+ mockMailRepository.send = jest.fn(option => null)
+
+ const serviceLocator = {
+ userRepository: mockUserRepository,
+ mailRepository: mockMailRepository
+ }
+ it('should return user with email inscription', async () => {
+
+ const user = await createUser(email,"password",serviceLocator)
+ expect(user.email).toBe(email)
+ expect(user.confirmed).toBe(false)
+ !expect(user.password).not.toBe(null)
+ });
+ it('should throw error 403 email already exists', async () => {
+ mockUserRepository.getByEmailOrPseudo = jest.fn((email,pseudo)=> 'something')
+ const error = await catchError(async ()=>{
+ await createUser(email,"password",serviceLocator)
+ })
+ expect(error.code).toBe(403);
+ });
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/user/getAccessToken.test.js b/test/unit/application/usecase/user/getAccessToken.test.js
new file mode 100644
index 0000000..6fbe806
--- /dev/null
+++ b/test/unit/application/usecase/user/getAccessToken.test.js
@@ -0,0 +1,93 @@
+const UserRepository = require("../../../../../lib/infrastructure/repositories/interfaces/UserRepositoryAbstract");
+const getAccessToken = require("../../../../../lib/application/use_cases/security/GetAccessToken");
+const bcrypt = require("bcrypt");
+const catchError = require("../utils/catchError");
+require("dotenv").config();
+
+describe("getAccessToken", () => {
+ it("should generate access token", async () => {
+ const passwordTest = "passwordTest";
+ const persistedUserCrypted = {
+ id_utilisateur: "id",
+ pseudo: "pseudo",
+ email: "email",
+ alias: "alias",
+ bio: "bio",
+ photo: "path/to/file",
+ photo_temporaire: "path/to/file",
+ password: await bcrypt.hash(passwordTest, 10),
+ token: "token",
+ is_private: false,
+ id_role: 1,
+ ban_until: new Date("10-06-2003"),
+ };
+ const expectedAccessToken = {
+ user: {
+ id_utilisateur: "id",
+ pseudo: "pseudo",
+ email: "email",
+ alias: "alias",
+ bio: "bio",
+ photo: `${process.env.API_URL}/path/to/file`,
+ photo_temporaire: `${process.env.API_URL}/path/to/file`,
+ type: "user",
+ is_private: false,
+ id_role: 1,
+ ban_until: new Date("10-06-2003"),
+ },
+ token: 1,
+ };
+ const mockUserRepository = new UserRepository();
+ const mockAccessTokenManager = {};
+ mockAccessTokenManager.generate = jest.fn((uid) => 1);
+ mockUserRepository.getByIdent = jest.fn((ident) => persistedUserCrypted);
+ expect(
+ await getAccessToken(persistedUserCrypted.pseudo, passwordTest, {
+ userRepository: mockUserRepository,
+ accessTokenManager: mockAccessTokenManager,
+ })
+ ).toEqual(expectedAccessToken);
+ });
+
+ it("should throw an error because the password is incorrect", async () => {
+ const passwordTest = "passwordTest";
+ const persistedUserCrypted = {
+ id_utilisateur: "id",
+ pseudo: "pseudo",
+ email: "email",
+ alias: "alias",
+ bio: "bio",
+ photo: "path/to/file",
+ photo_temporaire: "path/to/file",
+ password: await bcrypt.hash(passwordTest, 10),
+ token: "token",
+ id_role: 1,
+ ban_until: new Date("10-06-2003"),
+ };
+ const mockUserRepository = new UserRepository();
+ const mockAccessTokenManager = {};
+ mockUserRepository.getByIdent = jest.fn((ident) => persistedUserCrypted);
+ const error = await catchError(async () => {
+ await getAccessToken(persistedUserCrypted.pseudo, "badPassword", {
+ userRepository: mockUserRepository,
+ accessTokenManager: mockAccessTokenManager,
+ });
+ });
+
+ expect(error.code).toBe(401);
+ });
+
+ it("should throw an error because the user doesnt exists", async () => {
+ const mockUserRepository = new UserRepository();
+ const mockAccessTokenManager = {};
+ mockUserRepository.getByIdent = jest.fn((ident) => null);
+ const error = await catchError(async () => {
+ await getAccessToken("", "", {
+ userRepository: mockUserRepository,
+ accessTokenManager: mockAccessTokenManager,
+ });
+ });
+ console.log(error);
+ expect(error.code).toBe(401);
+ });
+});
diff --git a/test/unit/application/usecase/user/getOeuvreFav.test.js b/test/unit/application/usecase/user/getOeuvreFav.test.js
new file mode 100644
index 0000000..46150b2
--- /dev/null
+++ b/test/unit/application/usecase/user/getOeuvreFav.test.js
@@ -0,0 +1,64 @@
+const getOeuvresFav = require("../../../../../lib/application/use_cases/user/getOeuvresFav.js")
+const throwStatusCode = require("../../../../../lib/application/use_cases/utils/throwStatusCode.js")
+const catchError = require("../utils/catchError.js")
+
+describe("getOeuvresFav Test", () => {
+ const userToken = 'token'
+
+ const mockAccesTokenManager = {}
+ const mockSpotifyRepository = {}
+ const mockUserRepository = {}
+ const mockOeuvreFavRepository = {}
+ const serviceLocator = {
+ userRepository: mockUserRepository,
+ oeuvreFavRepository: mockOeuvreFavRepository,
+ accessTokenManager: mockAccesTokenManager,
+ spotifyRepository: mockSpotifyRepository,
+ }
+
+ describe("invalid and valid cases", () => {
+
+ it("should throw error bad auth token", async () => {
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((userToken) => null)
+ const error = await catchError(async () => {
+ await getOeuvresFav(userToken, serviceLocator)
+ })
+ expect(error.code).toBe(401)
+ })
+
+ it("should send an array with oeuvre fav id", async () => {
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((userToken) => {
+ return {
+ id_utilisateur: 1
+ }
+ })
+ mockOeuvreFavRepository.getOeuvresFav = jest.fn((userToken) => {
+ return [1, 2, 3]
+ })
+
+ const result = await getOeuvresFav(userToken, serviceLocator)
+
+ expect(result).toEqual([1, 2, 3])
+ expect(mockOeuvreFavRepository.getOeuvresFav).toHaveBeenCalledTimes(1)
+ })
+
+ it("should send a empty array", async () => {
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1)
+ mockUserRepository.getByUser = jest.fn((userToken) => {
+ return {
+ id_utilisateur: 1
+ }
+ })
+ mockOeuvreFavRepository.getOeuvresFav = jest.fn((userToken) => {
+ return []
+ })
+
+ const result = await getOeuvresFav(userToken, serviceLocator)
+
+ expect(result).toEqual([])
+ expect(mockOeuvreFavRepository.getOeuvresFav).toHaveBeenCalledTimes(1)
+ })
+ })
+})
diff --git a/test/unit/application/usecase/user/getUserByConfirmToken.test.js b/test/unit/application/usecase/user/getUserByConfirmToken.test.js
new file mode 100644
index 0000000..c0c4f4f
--- /dev/null
+++ b/test/unit/application/usecase/user/getUserByConfirmToken.test.js
@@ -0,0 +1,49 @@
+const getUserByConfirmToken = require("../../../../../lib/application/use_cases/user/getUserByConfirmToken");
+const mockUser = {
+ id_utilisateur: 1,
+ pseudo: "pseudo",
+ alias: "alias",
+ email: "testemail@gmail.com",
+ photo: "path/to/file",
+ photo_temporaire: "path/to/file",
+ token: "token",
+ refresh_token: "refreshToken",
+ password: "password",
+ id_role: 1,
+ ban_until: null,
+ confirmed: false,
+ confirm_token: "fezfezgezrhgez",
+ type: "user",
+};
+const expectedUser = {
+ id_utilisateur: 1,
+ pseudo: "pseudo",
+ alias: "alias",
+ email: "testemail@gmail.com",
+ photo: `${process.env.API_URL}/path/to/file`,
+ photo_temporaire: `${process.env.API_URL}/path/to/file`,
+ id_role: 1,
+ ban_until: null,
+ type: "user",
+};
+const mockUserRepository = {};
+describe("getUserByPseudo", () => {
+ afterEach(async () => {
+ jest.clearAllMocks();
+ });
+ it("should return Public User", async () => {
+ console.log("test");
+ mockUserRepository.getByConfirmToken = jest.fn(() => mockUser);
+ const result = await getUserByConfirmToken("test", {
+ userRepository: mockUserRepository,
+ });
+ expect(result).toEqual(expectedUser);
+ });
+ it("should return null", async () => {
+ mockUserRepository.getByConfirmToken = jest.fn(() => null);
+ const result = await getUserByConfirmToken("test", {
+ userRepository: mockUserRepository,
+ });
+ expect(result).toBeNull();
+ });
+});
diff --git a/test/unit/application/usecase/user/getUserByPseudo.test.js b/test/unit/application/usecase/user/getUserByPseudo.test.js
new file mode 100644
index 0000000..fa1e35d
--- /dev/null
+++ b/test/unit/application/usecase/user/getUserByPseudo.test.js
@@ -0,0 +1,49 @@
+require("dotenv").config();
+const getUserBuPseudo = require("../../../../../lib/application/use_cases/user/getUserByPseudo");
+const mockUser = {
+ id_utilisateur: 1,
+ pseudo: "pseudo",
+ alias: "alias",
+ email: "testemail@gmail.com",
+ photo: "path/to/file",
+ photo_temporaire: "path/to/file",
+ token: "token",
+ refresh_token: "refreshToken",
+ password: "password",
+ id_role: 1,
+ ban_until: null,
+ confirmed: false,
+ confirm_token: "fezfezgezrhgez",
+ type: "user",
+};
+const expectedUser = {
+ id_utilisateur: 1,
+ pseudo: "pseudo",
+ alias: "alias",
+ email: "testemail@gmail.com",
+ photo: `${process.env.API_URL}/path/to/file`,
+ photo_temporaire: `${process.env.API_URL}/path/to/file`,
+ id_role: 1,
+ ban_until: null,
+ type: "user",
+};
+const mockUserRepository = {};
+describe("getUserByPseudo", () => {
+ afterEach(async () => {
+ jest.clearAllMocks();
+ });
+ it("should return Public User", async () => {
+ mockUserRepository.getByEmailOrPseudo = jest.fn(() => mockUser);
+ const result = await getUserBuPseudo("test", {
+ userRepository: mockUserRepository,
+ });
+ expect(result).toEqual(expectedUser);
+ });
+ it("should return null", async () => {
+ mockUserRepository.getByEmailOrPseudo = jest.fn(() => null);
+ const result = await getUserBuPseudo("test", {
+ userRepository: mockUserRepository,
+ });
+ expect(result).toBeNull();
+ });
+});
diff --git a/test/unit/application/usecase/user/oeuvreFav.test.js b/test/unit/application/usecase/user/oeuvreFav.test.js
new file mode 100644
index 0000000..30afe5e
--- /dev/null
+++ b/test/unit/application/usecase/user/oeuvreFav.test.js
@@ -0,0 +1,239 @@
+const OeuvreFav = require("../../../../../lib/application/use_cases/user/oeuvreFav.js");
+const throwStatusCode = require("../../../../../lib/application/use_cases/utils/throwStatusCode.js");
+const catchError = require("../utils/catchError.js");
+const {
+ albumRawOneArtist,
+} = require("../../../interfaces/serializers/fixtures/albumFixture.js");
+const {
+ rawTrackWithOneArtist,
+} = require("../../../interfaces/serializers/fixtures/albumTrackFixture.js");
+
+describe("OeuvreFav Test", () => {
+ const idOeuvre = "idOeuvre";
+ const userToken = "token";
+
+ const mockAccesTokenManager = {};
+ const mockSpotifyRepository = {};
+ const mockUserRepository = {};
+ const mockOeuvreFavRepository = {};
+ const serviceLocator = {
+ userRepository: mockUserRepository,
+ oeuvreFavRepository: mockOeuvreFavRepository,
+ accessTokenManager: mockAccesTokenManager,
+ spotifyRepository: mockSpotifyRepository,
+ };
+
+ describe("invalid and valid cases", () => {
+ it("should throw error bad auth token", async () => {
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1);
+ mockUserRepository.getByUser = jest.fn((userToken) => null);
+ const error = await catchError(async () => {
+ await OeuvreFav(userToken, "track", idOeuvre, serviceLocator);
+ });
+ expect(error.code).toBe(401);
+ });
+
+ // aucune oeuvre de trouve
+ it("should throw incrorrect id oeuvre error", async () => {
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1);
+ mockUserRepository.getByUser = jest.fn((userToken) => {
+ return {
+ id_utilisateur: 1,
+ };
+ });
+
+ mockSpotifyRepository.getOeuvre = jest.fn((idOeuvre) => {
+ throwStatusCode(404, "invalid id");
+ });
+ const error = await catchError(async () => {
+ await OeuvreFav(userToken, "track", idOeuvre, serviceLocator);
+ });
+ expect(error.code).toBe(404);
+
+ expect(mockSpotifyRepository.getOeuvre).toHaveBeenCalledTimes(1);
+ });
+
+ // plus de 3 oeuvres favorites avec album
+ it("should throw maximal add", async () => {
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1);
+ mockUserRepository.getByUser = jest.fn((userToken) => {
+ return {
+ id_utilisateur: 1,
+ };
+ });
+ mockSpotifyRepository.getOeuvre = jest.fn((idOeuvre) => {
+ return Promise.resolve(albumRawOneArtist);
+ });
+ mockOeuvreFavRepository.oeuvreFavExists = jest.fn(
+ (id_utilisateur, idOeuvre) => false
+ );
+ mockOeuvreFavRepository.ajoutPossible = jest.fn(
+ (id_utilisateur, idOeuvre) => false
+ );
+
+ const error = await catchError(async () => {
+ await OeuvreFav(userToken, "track", idOeuvre, serviceLocator);
+ });
+
+ expect(mockOeuvreFavRepository.ajoutPossible).toHaveBeenCalledTimes(1);
+ expect(error.code).toBe(403);
+ });
+
+ // plus de 3 oeuvres favorites avec track
+ it("should throw maximal add", async () => {
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1);
+ mockUserRepository.getByUser = jest.fn((userToken) => {
+ return {
+ id_utilisateur: 1,
+ };
+ });
+
+ mockSpotifyRepository.getOeuvre = jest.fn((idOeuvre) => {
+ return Promise.resolve(rawTrackWithOneArtist);
+ });
+ mockOeuvreFavRepository.oeuvreFavExists = jest.fn(
+ (id_utilisateur, idOeuvre) => false
+ );
+ mockOeuvreFavRepository.ajoutPossible = jest.fn(
+ (id_utilisateur, idOeuvre) => false
+ );
+
+ const error = await catchError(async () => {
+ await OeuvreFav(userToken, "track", idOeuvre, serviceLocator);
+ });
+
+ expect(mockSpotifyRepository.getOeuvre).toHaveBeenCalledTimes(1);
+
+ expect(mockOeuvreFavRepository.ajoutPossible).toHaveBeenCalledTimes(1);
+ expect(error.code).toBe(403);
+ });
+
+ // ajout réussie avec album
+ it("should put an album", async () => {
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1);
+ mockUserRepository.getByUser = jest.fn((userToken) => {
+ return {
+ id_utilisateur: 1,
+ };
+ });
+ mockSpotifyRepository.getOeuvre = jest.fn((idOeuvre) => {
+ return Promise.resolve(albumRawOneArtist);
+ });
+ mockOeuvreFavRepository.oeuvreFavExists = jest.fn(
+ (id_utilisateur, idOeuvre) => false
+ );
+ mockOeuvreFavRepository.ajoutPossible = jest.fn(
+ (id_utilisateur, idOeuvre) => true
+ );
+ mockOeuvreFavRepository.addOeuvrefav = jest.fn();
+
+ const result = await OeuvreFav(
+ userToken,
+ "track",
+ idOeuvre,
+ serviceLocator
+ );
+
+ expect(mockOeuvreFavRepository.ajoutPossible).toHaveBeenCalledTimes(1);
+ expect(mockOeuvreFavRepository.addOeuvrefav).toHaveBeenCalledTimes(1);
+ expect(result).toEqual(true);
+ });
+
+ // ajout réussie avec track
+ it("should put an track", async () => {
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1);
+ mockUserRepository.getByUser = jest.fn((userToken) => {
+ return {
+ id_utilisateur: 1,
+ };
+ });
+
+ mockSpotifyRepository.getOeuvre = jest.fn((idOeuvre) => {
+ return Promise.resolve(rawTrackWithOneArtist);
+ });
+ mockOeuvreFavRepository.oeuvreFavExists = jest.fn(
+ (id_utilisateur, idOeuvre) => false
+ );
+ mockOeuvreFavRepository.ajoutPossible = jest.fn(
+ (id_utilisateur, idOeuvre) => true
+ );
+ mockOeuvreFavRepository.addOeuvrefav = jest.fn();
+
+ const result = await OeuvreFav(
+ userToken,
+ "track",
+ idOeuvre,
+ serviceLocator
+ );
+
+ expect(mockSpotifyRepository.getOeuvre).toHaveBeenCalledTimes(1);
+
+ expect(mockOeuvreFavRepository.ajoutPossible).toHaveBeenCalledTimes(1);
+ expect(mockOeuvreFavRepository.addOeuvrefav).toHaveBeenCalledTimes(1);
+ expect(result).toEqual(true);
+ });
+
+ // supression réussite d'un album
+ it("should remove an album ", async () => {
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1);
+ mockUserRepository.getByUser = jest.fn((userToken) => {
+ return {
+ id_utilisateur: 1,
+ };
+ });
+ mockSpotifyRepository.getOeuvre = jest.fn((idOeuvre) => {
+ return Promise.resolve(albumRawOneArtist);
+ });
+ mockOeuvreFavRepository.oeuvreFavExists = jest.fn(
+ (id_utilisateur, idOeuvre) => true
+ );
+ mockOeuvreFavRepository.ajoutPossible = jest.fn();
+ mockOeuvreFavRepository.addOeuvrefav = jest.fn();
+ mockOeuvreFavRepository.deleteOeuvrefav = jest.fn();
+
+ const result = await OeuvreFav(
+ userToken,
+ "track",
+ idOeuvre,
+ serviceLocator
+ );
+
+ expect(mockOeuvreFavRepository.ajoutPossible).not.toHaveBeenCalled();
+ expect(mockOeuvreFavRepository.deleteOeuvrefav).toHaveBeenCalledTimes(1);
+ expect(result).toEqual(false);
+ });
+
+ // supression réussite d'une track
+ it("should remove a track ", async () => {
+ mockAccesTokenManager.decode = jest.fn((userToken) => 1);
+ mockUserRepository.getByUser = jest.fn((userToken) => {
+ return {
+ id_utilisateur: 1,
+ };
+ });
+
+ mockSpotifyRepository.getOeuvre = jest.fn((idOeuvre) => {
+ return Promise.resolve(rawTrackWithOneArtist);
+ });
+ mockOeuvreFavRepository.oeuvreFavExists = jest.fn(
+ (id_utilisateur, idOeuvre) => true
+ );
+ mockOeuvreFavRepository.ajoutPossible = jest.fn();
+ mockOeuvreFavRepository.addOeuvrefav = jest.fn();
+ mockOeuvreFavRepository.deleteOeuvrefav = jest.fn();
+
+ const result = await OeuvreFav(
+ userToken,
+ "track",
+ idOeuvre,
+ serviceLocator
+ );
+
+ expect(mockSpotifyRepository.getOeuvre).toHaveBeenCalledTimes(1);
+
+ expect(mockOeuvreFavRepository.ajoutPossible).not.toHaveBeenCalled();
+ expect(mockOeuvreFavRepository.deleteOeuvrefav).toHaveBeenCalledTimes(1);
+ expect(result).toEqual(false);
+ });
+ });
+});
diff --git a/test/unit/application/usecase/user/resetPassword.test.js b/test/unit/application/usecase/user/resetPassword.test.js
new file mode 100644
index 0000000..552217c
--- /dev/null
+++ b/test/unit/application/usecase/user/resetPassword.test.js
@@ -0,0 +1,26 @@
+const mockUserRepository = {}
+const resetPassword = require("../../../../../lib/application/use_cases/user/resetPassword")
+const serviceLocator = {
+ userRepository: mockUserRepository
+}
+require("dotenv").config()
+const catchError = require("../utils/catchError")
+const bcrypt = require("bcrypt");
+describe("sendResetEmail", ()=>{
+ it("should return true",async ()=>{
+ mockUserRepository.getByResetToken = jest.fn(()=>{return {id:"test"}})
+ mockUserRepository.updateUser = jest.fn(()=>{})
+ const result = await resetPassword("testPassword","token",serviceLocator)
+ expect(result.password).not.toBe("test");
+ expect(mockUserRepository.updateUser).toHaveBeenCalledTimes(1)
+ })
+ it("should return error",async ()=>{
+ mockUserRepository.getByResetToken = jest.fn(()=>{})
+ mockUserRepository.updateUser = jest.fn(()=>{})
+ const error = await catchError(async () =>{
+ await resetPassword("testPassword","token",serviceLocator)
+ })
+ expect(error.code).toBe(400)
+ })
+
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/user/sendResetEmail.test.js b/test/unit/application/usecase/user/sendResetEmail.test.js
new file mode 100644
index 0000000..fc36b26
--- /dev/null
+++ b/test/unit/application/usecase/user/sendResetEmail.test.js
@@ -0,0 +1,29 @@
+const mockMailRepository = {}
+const mockUserRepository = {}
+const sendResetEmail = require("../../../../../lib/application/use_cases/user/sendResetEmail")
+const serviceLocator = {
+ mailRepository: mockMailRepository,
+ userRepository: mockUserRepository
+}
+describe("sendResetEmail", ()=>{
+ it("should return true",async ()=>{
+ mockMailRepository.send = jest.fn(()=>{})
+ mockUserRepository.getByEmailOrPseudo = jest.fn(()=>{return {reset_token: 1,confirmed: true}})
+ mockUserRepository.updateUser = jest.fn(()=>{})
+
+ expect(await sendResetEmail("testemail",serviceLocator)).toBe(true);
+ expect(mockMailRepository.send).toHaveBeenCalledTimes(1)
+ })
+ it("should return false because the user is not confirmed",async ()=>{
+ mockMailRepository.send = jest.fn(()=>{})
+ mockUserRepository.getByEmailOrPseudo = jest.fn(()=>{return {reset_token: 1,confirmed:false}})
+ mockUserRepository.updateUser = jest.fn(()=>{})
+ expect(await sendResetEmail("testemail",serviceLocator)).toBe(false);
+ })
+ it("should return false because the user doesn't exists",async ()=>{
+ mockMailRepository.send = jest.fn(()=>{})
+ mockUserRepository.getByEmailOrPseudo = jest.fn(()=>{return null})
+ mockUserRepository.updateUser = jest.fn(()=>{})
+ expect(await sendResetEmail("testemail",serviceLocator)).toBe(false);
+ })
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/user/uploadPreview.test.js b/test/unit/application/usecase/user/uploadPreview.test.js
new file mode 100644
index 0000000..72dae52
--- /dev/null
+++ b/test/unit/application/usecase/user/uploadPreview.test.js
@@ -0,0 +1,91 @@
+mockAccessTokenManager = {}
+mockUserRepository = {}
+mockDocumentRepository = {}
+mockID = 12424
+const uploadPreview = require("../../../../../lib/application/use_cases/user/uploadPreview")
+const catchError = require("../utils/catchError");
+const mockFile = {
+ hapi: {
+ filename: "test.png",
+ headers: {
+ 'content-type' : 'image/png'
+ }
+ },
+ _data: "testDFata"
+}
+mockAccessTokenManager.decode = jest.fn((token) => mockID)
+mockUserRepository.getByUser = jest.fn((id) => 'something')
+mockUserRepository.addPreviewPath = jest.fn((id,path) => {})
+mockDocumentRepository.deleteFile = jest.fn((path) => path)
+mockUserRepository.getPreviewPath = jest.fn((id) => null)
+mockDocumentRepository.uploadFile = jest.fn((path,file) => path)
+describe("uploadPreview usecase", ()=>{
+ describe("valid upload preview cases", ()=>{
+ it('should upload the image without deleting previous file',async() =>{
+ mockUserRepository.getPreviewPath = jest.fn((id) => null)
+ const path = await uploadPreview(mockFile,'token', {
+ accessTokenManager: mockAccessTokenManager,
+ userRepository: mockUserRepository,
+ documentRepository: mockDocumentRepository
+ })
+ expect(path).not.toBeNull()
+ expect(mockDocumentRepository.deleteFile).toHaveBeenCalledTimes(0)
+ } )
+ it('should upload the image and deleting previous file',async() =>{
+ mockUserRepository.getPreviewPath = jest.fn((id) => 'path')
+ const path = await uploadPreview(mockFile,'token', {
+ accessTokenManager: mockAccessTokenManager,
+ userRepository: mockUserRepository,
+ documentRepository: mockDocumentRepository
+ })
+ expect(path).not.toBeNull()
+ expect(mockDocumentRepository.deleteFile).toHaveBeenCalledTimes(1)
+ } )
+ })
+ describe("invalid upload preview cases", ()=> {
+
+ const invalidMockFile = {
+ hapi: {
+ filename: "test.rpg",
+ headers: {
+ 'content-type' : 'image/rpg'
+ }
+ },
+ _data: "testDFata"
+ }
+ it('should throw 415 error',async() =>{
+ const error = await catchError(async ()=>{
+ await uploadPreview(invalidMockFile,'token', {
+ accessTokenManager: mockAccessTokenManager,
+ userRepository: mockUserRepository,
+ documentRepository: mockDocumentRepository
+ })
+ })
+ expect(error.code).toBe(415)
+ } )
+ it('should throw 500 error',async() =>{
+ mockDocumentRepository.uploadFile = jest.fn((path,file) => null)
+ const error = await catchError(async ()=>{
+ await uploadPreview(mockFile,'token', {
+ accessTokenManager: mockAccessTokenManager,
+ userRepository: mockUserRepository,
+ documentRepository: mockDocumentRepository
+ })
+ })
+ expect(error.code).toBe(500)
+
+ } )
+ it('should throw 401 error',async() =>{
+ mockUserRepository.getByUser = jest.fn((id) => null)
+ const error = await catchError(async ()=>{
+ await uploadPreview(mockFile,'token', {
+ accessTokenManager: mockAccessTokenManager,
+ userRepository: mockUserRepository,
+ documentRepository: mockDocumentRepository
+ })
+ })
+ expect(error.code).toBe(401)
+ } )
+ })
+
+})
\ No newline at end of file
diff --git a/test/unit/application/usecase/user/user.test.js b/test/unit/application/usecase/user/user.test.js
deleted file mode 100644
index 39572ad..0000000
--- a/test/unit/application/usecase/user/user.test.js
+++ /dev/null
@@ -1,149 +0,0 @@
-
-const createUser = require('../../../../../lib/application/use_cases/user/CreateUser')
-const UserRepository = require('../../../../../lib/infrastructure/repositories/interfaces/UserRepositoryAbstract');
-const getAccessToken = require('../../../../../lib/application/use_cases/security/GetAccessToken')
-const User = require('../../../../../lib/domain/model/User')
-const bcrypt = require("bcrypt");
-const {use} = require("bcrypt/promises");
-const persistedUser = new User(
- 1,
- 'testPeudo',
- 'testEmail@gmail.com',
- 'test_alias',
- 'testbio',
- 'passwordtest',
- 'spotifyToken',
- 2,
- 1)
-
-
-describe('createUser', () =>{
- it("should create an user", async () =>{
- const mockUserRepository = new UserRepository();
- mockUserRepository.persist = jest.fn(() => persistedUser)
- mockUserRepository.getByEmailOrPseudo = jest.fn((email,pseudo) => null)
- const user = await createUser(
- 'testPeudo',
- 'testEmail@gmail.com',
- 'test_alias',
- 'testbio',
- 'passwordtest',
- 'spotifyToken',
- {userRepository : mockUserRepository}
- )
- const mockResult = mockUserRepository.persist.mock.calls[0][0]
- expect(mockUserRepository.persist).toHaveBeenCalled()
- expect(mockResult.id).toBe(null)
- expect(mockResult.pseudo).toBe(persistedUser.pseudo)
- expect(mockResult.email).toBe(persistedUser.email)
- expect(mockResult.alias).toBe(persistedUser.alias)
- expect(mockResult.bio).toBe(persistedUser.bio)
- expect(mockResult.spotifyToken).toBe(persistedUser.spotifyToken)
- expect(mockResult.id_role).toBe(2)
- expect(mockResult.id_etat).toBe(1)
- expect(mockResult.password).not.toBe(user.password)
- })
- it('should throw an error when an user with the same pseudo exists', async ()=>{
- const mockUserRepository = new UserRepository();
- mockUserRepository.persist = jest.fn(() => persistedUser)
- mockUserRepository.getByEmailOrPseudo = jest.fn((email,pseudo) => persistedUser)
- await expect(createUser(
- persistedUser.pseudo,
- '',
- '',
- '',
- '',
- '',
- {userRepository: mockUserRepository}
- )).rejects.toThrow('Email ou Pseudo déjà existant')
- })
- it('should throw an error when an user with the same email exists', async ()=>{
- const mockUserRepository = new UserRepository();
- mockUserRepository.persist = jest.fn(() => persistedUser)
- mockUserRepository.getByEmailOrPseudo = jest.fn((email,pseudo) => persistedUser)
- await expect(createUser(
- '',
- persistedUser.email,
- '',
- '',
- '',
- '',
- {userRepository: mockUserRepository}
- )).rejects.toThrow('Email ou Pseudo déjà existant')
- })
-
-})
-
-describe('getAccessToken', () =>{
- it('should generate access token', async () =>{
- const passwordTest = 'passwordTest'
- const persistedUserCrypted = new User(
- 1,
- 'testPeudo',
- 'testEmail@gmail.com',
- 'test_alias',
- 'testbio',
- await bcrypt.hash(passwordTest,10),
- 'spotifyToken',
- 2,
- 1)
- const mockUserRepository = new UserRepository();
- const mockAccessTokenManager = {};
- mockAccessTokenManager.generate = jest.fn((uid) => 1)
- mockUserRepository.getByIdent = jest.fn((ident) => persistedUserCrypted)
- expect(
- await getAccessToken(
- persistedUserCrypted.pseudo,
- passwordTest,
- {
- userRepository : mockUserRepository,
- accessTokenManager: mockAccessTokenManager
- }
- )
- ).toBe(1)
- })
-
-
- it('should throw an error because the password is incorrect', async () =>{
- const passwordTest = 'passwordTest'
- const persistedUserCrypted = new User(
- 1,
- 'testPeudo',
- 'testEmail@gmail.com',
- 'test_alias',
- 'testbio',
- await bcrypt.hash(passwordTest,10),
- 'spotifyToken',
- 2,
- 1)
- const mockUserRepository = new UserRepository();
- const mockAccessTokenManager = {};
- mockUserRepository.getByIdent = jest.fn((ident) => persistedUserCrypted)
- await expect(
- getAccessToken(
- persistedUserCrypted.pseudo,
- 'badPassword',
- {
- userRepository : mockUserRepository,
- accessTokenManager: mockAccessTokenManager
- }
- )
- ).rejects.toThrow('Bad credentials')
- })
-
- it('should throw an error because the user doesnt exists', async () =>{
- const mockUserRepository = new UserRepository();
- const mockAccessTokenManager = {};
- mockUserRepository.getByIdent = jest.fn((ident) => null)
- await expect(
- getAccessToken(
- '',
- '',
- {
- userRepository : mockUserRepository,
- accessTokenManager: mockAccessTokenManager
- }
- )
- ).rejects.toThrow('Bad credentials')
- })
-})
\ No newline at end of file
diff --git a/test/unit/application/usecase/utils/catchError.js b/test/unit/application/usecase/utils/catchError.js
new file mode 100644
index 0000000..3f78d81
--- /dev/null
+++ b/test/unit/application/usecase/utils/catchError.js
@@ -0,0 +1,8 @@
+module.exports = async (action) => {
+ try{
+ await action()
+ }catch (error){
+ return error
+ }
+ return null
+}
\ No newline at end of file
diff --git a/test/unit/infrastructure/repositories/DocumentRepository.test.js b/test/unit/infrastructure/repositories/DocumentRepository.test.js
new file mode 100644
index 0000000..d510cb3
--- /dev/null
+++ b/test/unit/infrastructure/repositories/DocumentRepository.test.js
@@ -0,0 +1,25 @@
+const DocumentRepositoryTest = require("../../../../lib/infrastructure/repositories/DocumentRepository")
+const createUser = require("../../../../lib/application/use_cases/user/CompleteAccount");
+let filePath
+const documentRepository = new DocumentRepositoryTest();
+const mockFile = {
+ hapi: {
+ filename: "test.png"
+ },
+ _data: "testDFata"
+}
+describe('document repository', ()=>{
+ describe('document repository with no problem', ()=>{
+ it('should create file without problem', async () =>{
+ filePath= await documentRepository.uploadFile("test/unit/infrastructure/repositories/testFolder", mockFile)
+ })
+ it('should creadzadte file without problem', async () =>{
+ documentRepository.deleteFile(filePath)
+ })
+ })
+ describe('document repository with errors', () =>{
+ it("shouldn't create file", async () =>{
+ await expect(documentRepository.uploadFile("test/unit/infrastructure/repositories/testFolder",{})).rejects.toThrow()
+ })
+ })
+})
\ No newline at end of file
diff --git a/test/unit/infrastructure/repositories/testFolder/1593d51b7bec762dc17fbc8833c18c7c.png b/test/unit/infrastructure/repositories/testFolder/1593d51b7bec762dc17fbc8833c18c7c.png
new file mode 100644
index 0000000..84decf0
--- /dev/null
+++ b/test/unit/infrastructure/repositories/testFolder/1593d51b7bec762dc17fbc8833c18c7c.png
@@ -0,0 +1 @@
+testDFata
\ No newline at end of file
diff --git a/test/unit/interfaces/serializers/AlbumSerializer.test.js b/test/unit/interfaces/serializers/AlbumSerializer.test.js
index 09edb99..f835ac2 100644
--- a/test/unit/interfaces/serializers/AlbumSerializer.test.js
+++ b/test/unit/interfaces/serializers/AlbumSerializer.test.js
@@ -7,6 +7,7 @@ const {
albumRawNoArtist,
expectedAlbumNoArtist
} = require("./fixtures/albumFixture")
+
describe('albumSerialize', () => {
it("should return serialized album with one artist", ()=>{
const result = serializeAlbum(albumRawOneArtist)
diff --git a/test/unit/interfaces/serializers/AlbumTrackSerializer.test.js b/test/unit/interfaces/serializers/AlbumTrackSerializer.test.js
new file mode 100644
index 0000000..3bedde1
--- /dev/null
+++ b/test/unit/interfaces/serializers/AlbumTrackSerializer.test.js
@@ -0,0 +1,25 @@
+const serializeTrack = require("../../../../lib/interfaces/serializers/AlbumTrackSerializer")
+const {
+ expectedRawTrackWithOneArtist,
+ rawTrackWithOneArtist,
+ expectedRawTrackWithServeralArtists,
+ rawTrackWithServeralArtists,
+ expectedRawTrackWithNoArtist,
+ rawTrackWithNoArtist,
+} = require("./fixtures/albumTrackFixture")
+
+describe('AlbumTrackSerializer', () => {
+ it("should return serialized track with one artist", ()=>{
+ const result = serializeTrack(rawTrackWithOneArtist)
+ expect(result).toEqual(expectedRawTrackWithOneArtist)
+ })
+
+ it("should return serialized track with several artists", ()=>{
+ const result = serializeTrack(rawTrackWithServeralArtists)
+ expect(result).toEqual(expectedRawTrackWithServeralArtists)
+ })
+ it("should return serialized track with no artist", ()=>{
+ const result = serializeTrack(rawTrackWithNoArtist)
+ expect(result).toEqual(expectedRawTrackWithNoArtist)
+ })
+});
\ No newline at end of file
diff --git a/test/unit/interfaces/serializers/fixtures/albumFixture.js b/test/unit/interfaces/serializers/fixtures/albumFixture.js
index 5a35a54..55dbab0 100644
--- a/test/unit/interfaces/serializers/fixtures/albumFixture.js
+++ b/test/unit/interfaces/serializers/fixtures/albumFixture.js
@@ -2,6 +2,16 @@ const {
artistFixture,
expectedFixture,
} = require("./artistFixture")
+
+const {
+ expectedRawTrackWithOneArtist,
+ rawTrackWithOneArtist,
+ expectedRawTrackWithServeralArtists,
+ rawTrackWithServeralArtists,
+ expectedRawTrackWithNoArtist,
+ rawTrackWithNoArtist,
+} = require('./albumTrackFixture')
+
const albumRawOneArtist = {
album_type: "album",
total_tracks: 14,
@@ -31,7 +41,8 @@ const albumRawOneArtist = {
genres: ["genre1", "genre2"],
artists: [
artistFixture
- ]
+ ],
+ tracks: undefined,
}
const expectedAlbumOneArtist = {
@@ -41,26 +52,11 @@ const expectedAlbumOneArtist = {
popularity:0,
release_date:"2009-02-16",
spotify_url: "https://open.spotify.com/album/17UiqpQyl8T8vVxz2Towjy",
- images:[
- {
- url:"https://i.scdn.co/image/ab67616d0000b2730b2e3999b189fa2a8a6a752f",
- height:640,
- width:640
- },
- {
- url:"https://i.scdn.co/image/ab67616d00001e020b2e3999b189fa2a8a6a752f",
- height:300,
- width:300
- },
- {
- url:"https://i.scdn.co/image/ab67616d000048510b2e3999b189fa2a8a6a752f",
- height:64,
- width:64
- }
- ],
+ image: "https://i.scdn.co/image/ab67616d0000b2730b2e3999b189fa2a8a6a752f",
artists:[
expectedFixture
],
+ tracks: undefined,
genres: ["genre1", "genre2"],
type:"album"
}
@@ -95,7 +91,9 @@ const albumRawSeveralArtist = {
artists: [
artistFixture,
artistFixture
- ]
+ ],
+ tracks: undefined,
+
}
const expectedAlbumSeveralArtist = {
@@ -105,27 +103,12 @@ const expectedAlbumSeveralArtist = {
popularity:0,
release_date:"2009-02-16",
spotify_url: "https://open.spotify.com/album/17UiqpQyl8T8vVxz2Towjy",
- images:[
- {
- url:"https://i.scdn.co/image/ab67616d0000b2730b2e3999b189fa2a8a6a752f",
- height:640,
- width:640
- },
- {
- url:"https://i.scdn.co/image/ab67616d00001e020b2e3999b189fa2a8a6a752f",
- height:300,
- width:300
- },
- {
- url:"https://i.scdn.co/image/ab67616d000048510b2e3999b189fa2a8a6a752f",
- height:64,
- width:64
- }
- ],
+ image: "https://i.scdn.co/image/ab67616d0000b2730b2e3999b189fa2a8a6a752f",
artists:[
expectedFixture,
expectedFixture
],
+ tracks: undefined,
genres: ["genre1", "genre2"],
type:"album"
}
@@ -154,6 +137,7 @@ const albumRawNoArtist = {
width: 64
}
],
+ tracks: undefined,
name: "Perdu D'Avance",
release_date: "2009-02-16",
genres: ["genre1", "genre2"],
@@ -166,24 +150,9 @@ const expectedAlbumNoArtist = {
popularity:0,
release_date:"2009-02-16",
spotify_url: "https://open.spotify.com/album/17UiqpQyl8T8vVxz2Towjy",
- images:[
- {
- url:"https://i.scdn.co/image/ab67616d0000b2730b2e3999b189fa2a8a6a752f",
- height:640,
- width:640
- },
- {
- url:"https://i.scdn.co/image/ab67616d00001e020b2e3999b189fa2a8a6a752f",
- height:300,
- width:300
- },
- {
- url:"https://i.scdn.co/image/ab67616d000048510b2e3999b189fa2a8a6a752f",
- height:64,
- width:64
- }
- ],
+ image: "https://i.scdn.co/image/ab67616d0000b2730b2e3999b189fa2a8a6a752f",
artists: undefined,
+ tracks: undefined,
genres: ["genre1", "genre2"],
type:"album"
}
diff --git a/test/unit/interfaces/serializers/fixtures/albumTrackFixture.js b/test/unit/interfaces/serializers/fixtures/albumTrackFixture.js
new file mode 100644
index 0000000..de2b5fa
--- /dev/null
+++ b/test/unit/interfaces/serializers/fixtures/albumTrackFixture.js
@@ -0,0 +1,251 @@
+const {
+ artistFixture,
+ expectedFixture,
+} = require("./artistFixture")
+
+
+const rawTrackWithOneArtist = {
+ id: "test_id",
+ name: "test_name",
+ external_urls: {
+ spotify: "https://open.spotify.com/track/4UVDKEPTgMQXv9UlIqVTcA"
+ },
+ artists: [
+ artistFixture
+ ],
+ duration_ms: 12121231,
+}
+
+const expectedRawTrackWithOneArtist = {
+ id:"test_id",
+ name:"test_name",
+ album: undefined,
+ artists:[
+ expectedFixture
+ ],
+ duration_ms:12121231,
+ popularity: undefined,
+ spotify_url:"https://open.spotify.com/track/4UVDKEPTgMQXv9UlIqVTcA",
+ type:"track"
+}
+
+const rawTrackWithServeralArtists = {
+ id: "test_id",
+ name: "test_name",
+ external_urls: {
+ spotify: "https://open.spotify.com/track/4UVDKEPTgMQXv9UlIqVTcA"
+ },
+ artists: [
+ artistFixture
+ ],
+ duration_ms: 12121231,
+}
+
+const expectedRawTrackWithServeralArtists = {
+ id:"test_id",
+ name:"test_name",
+ album: undefined,
+ artists:[
+ expectedFixture
+ ],
+ duration_ms:12121231,
+ popularity: undefined,
+ spotify_url:"https://open.spotify.com/track/4UVDKEPTgMQXv9UlIqVTcA",
+ type:"track"
+}
+
+
+const rawTrackWithNoArtist = {
+ id: "test_id",
+ name: "test_name",
+ external_urls: {
+ spotify: "https://open.spotify.com/track/4UVDKEPTgMQXv9UlIqVTcA"
+ },
+ artists: undefined,
+ duration_ms: 12121231,
+}
+
+const expectedRawTrackWithNoArtist = {
+ id:"test_id",
+ name:"test_name",
+ artists: undefined,
+ album: undefined,
+ duration_ms:12121231,
+ popularity: undefined,
+ spotify_url:"https://open.spotify.com/track/4UVDKEPTgMQXv9UlIqVTcA",
+ type:"track"
+}
+
+const albumRawOneArtist = {
+ album_type: "album",
+ total_tracks: 14,
+ external_urls: {
+ spotify: "https://open.spotify.com/album/17UiqpQyl8T8vVxz2Towjy"
+ },
+ id: "17UiqpQyl8T8vVxz2Towjy",
+ images: [
+ {
+ url: "https://i.scdn.co/image/ab67616d0000b2730b2e3999b189fa2a8a6a752f",
+ height: 640,
+ width: 640
+ },
+ {
+ url: "https://i.scdn.co/image/ab67616d00001e020b2e3999b189fa2a8a6a752f",
+ height: 300,
+ width: 300
+ },
+ {
+ url: "https://i.scdn.co/image/ab67616d000048510b2e3999b189fa2a8a6a752f",
+ height: 64,
+ width: 64
+ }
+ ],
+ name: "Perdu D'Avance",
+ release_date: "2009-02-16",
+ genres: ["genre1", "genre2"],
+ artists: [
+ artistFixture
+ ],
+ tracks: {items : [
+ rawTrackWithOneArtist
+ ]},
+}
+
+const expectedAlbumOneArtist = {
+ id:"17UiqpQyl8T8vVxz2Towjy",
+ total_tracks:14,
+ name:"Perdu D'Avance",
+ popularity:0,
+ release_date:"2009-02-16",
+ spotify_url: "https://open.spotify.com/album/17UiqpQyl8T8vVxz2Towjy",
+ image: "https://i.scdn.co/image/ab67616d0000b2730b2e3999b189fa2a8a6a752f",
+ artists:[
+ expectedFixture
+ ],
+ tracks: [
+ expectedRawTrackWithOneArtist
+
+ ],
+ genres: ["genre1", "genre2"],
+ type:"album"
+}
+
+const albumRawSeveralArtist = {
+ album_type: "album",
+ total_tracks: 14,
+ external_urls: {
+ spotify: "https://open.spotify.com/album/17UiqpQyl8T8vVxz2Towjy"
+ },
+ id: "17UiqpQyl8T8vVxz2Towjy",
+ images: [
+ {
+ url: "https://i.scdn.co/image/ab67616d0000b2730b2e3999b189fa2a8a6a752f",
+ height: 640,
+ width: 640
+ },
+ {
+ url: "https://i.scdn.co/image/ab67616d00001e020b2e3999b189fa2a8a6a752f",
+ height: 300,
+ width: 300
+ },
+ {
+ url: "https://i.scdn.co/image/ab67616d000048510b2e3999b189fa2a8a6a752f",
+ height: 64,
+ width: 64
+ }
+ ],
+ name: "Perdu D'Avance",
+ release_date: "2009-02-16",
+ genres: ["genre1", "genre2"],
+ artists: [
+ artistFixture,
+ artistFixture
+ ],
+ tracks: {
+ items: [
+ rawTrackWithServeralArtists
+ ],
+ }
+
+}
+
+const expectedAlbumSeveralArtist = {
+ id:"17UiqpQyl8T8vVxz2Towjy",
+ total_tracks:14,
+ name:"Perdu D'Avance",
+ popularity:0,
+ release_date:"2009-02-16",
+ spotify_url: "https://open.spotify.com/album/17UiqpQyl8T8vVxz2Towjy",
+ image: "https://i.scdn.co/image/ab67616d0000b2730b2e3999b189fa2a8a6a752f",
+ artists:[
+ expectedFixture,
+ expectedFixture
+ ],
+ tracks: [
+ expectedRawTrackWithServeralArtists
+ ],
+ genres: ["genre1", "genre2"],
+ type:"album"
+}
+
+const albumRawNoArtist = {
+ album_type: "album",
+ total_tracks: 14,
+ external_urls: {
+ spotify: "https://open.spotify.com/album/17UiqpQyl8T8vVxz2Towjy"
+ },
+ id: "17UiqpQyl8T8vVxz2Towjy",
+ images: [
+ {
+ url: "https://i.scdn.co/image/ab67616d0000b2730b2e3999b189fa2a8a6a752f",
+ height: 640,
+ width: 640
+ },
+ {
+ url: "https://i.scdn.co/image/ab67616d00001e020b2e3999b189fa2a8a6a752f",
+ height: 300,
+ width: 300
+ },
+ {
+ url: "https://i.scdn.co/image/ab67616d000048510b2e3999b189fa2a8a6a752f",
+ height: 64,
+ width: 64
+ }
+ ],
+ tracks: {items: [
+ rawTrackWithNoArtist
+ ]},
+ name: "Perdu D'Avance",
+ release_date: "2009-02-16",
+ genres: ["genre1", "genre2"],
+}
+
+const expectedAlbumNoArtist = {
+ id:"17UiqpQyl8T8vVxz2Towjy",
+ total_tracks:14,
+ name:"Perdu D'Avance",
+ popularity:0,
+ release_date:"2009-02-16",
+ spotify_url: "https://open.spotify.com/album/17UiqpQyl8T8vVxz2Towjy",
+ image: "https://i.scdn.co/image/ab67616d0000b2730b2e3999b189fa2a8a6a752f",
+ artists: undefined,
+ tracks: [
+ expectedRawTrackWithNoArtist
+ ],
+ genres: ["genre1", "genre2"],
+ type:"album"
+}
+module.exports = {
+ expectedRawTrackWithOneArtist,
+ rawTrackWithOneArtist,
+ expectedRawTrackWithServeralArtists,
+ rawTrackWithServeralArtists,
+ expectedRawTrackWithNoArtist,
+ rawTrackWithNoArtist,
+ albumRawOneArtist,
+ expectedAlbumOneArtist,
+ albumRawSeveralArtist,
+ expectedAlbumSeveralArtist,
+ albumRawNoArtist,
+ expectedAlbumNoArtist
+}
\ No newline at end of file
diff --git a/test/unit/interfaces/serializers/fixtures/artistAlbumsFixture.js b/test/unit/interfaces/serializers/fixtures/artistAlbumsFixture.js
new file mode 100644
index 0000000..1cb81eb
--- /dev/null
+++ b/test/unit/interfaces/serializers/fixtures/artistAlbumsFixture.js
@@ -0,0 +1,336 @@
+
+/* Artist */
+
+const artistFixture = {
+ external_urls: {
+ spotify: "https://open.spotify.com/artist/3fMbdgg4jU18AjLCKBhRSm"
+ },
+ id: "3fMbdgg4jU18AjLCKBhRSm",
+ name: "Michael Jackson",
+ popularity: 81,
+ genres: ["r&b", "soul"],
+ "images": [
+ {
+ "url": "https://i.scdn.co/image/ab6761610000e5eb0e08ea2c4d6789fbf5cbe0aa",
+ "height": 640,
+ "width": 640
+ },
+ {
+ "url": "https://i.scdn.co/image/ab676161000051740e08ea2c4d6789fbf5cbe0aa",
+ "height": 320,
+ "width": 320
+ },
+ {
+ "url": "https://i.scdn.co/image/ab6761610000f1780e08ea2c4d6789fbf5cbe0aa",
+ "height": 160,
+ "width": 160
+ }
+ ]
+}
+
+const artistExpectedFixture = {
+ id: "3fMbdgg4jU18AjLCKBhRSm",
+ name: "Michael Jackson",
+ image: "https://i.scdn.co/image/ab6761610000e5eb0e08ea2c4d6789fbf5cbe0aa",
+ popularity: 81,
+ genres: ["r&b", "soul"],
+ spotify_url: "https://open.spotify.com/artist/3fMbdgg4jU18AjLCKBhRSm",
+ type: "artist",
+}
+
+
+
+
+/* Pour appearsOn */
+const artistFixtureAppearsOn = {
+ external_urls: {
+ spotify: "https://open.spotify.com/artist/3TVXtAsR1Inumwj472S9r4"
+ },
+ id: "3TVXtAsR1Inumwj472S9r4",
+ name: "Drake",
+ popularity: 97,
+ genres: ["canadian hip hop","canadian pop","hip hop","pop rap","rap"],
+ "images": [
+ {
+ "url": "https://i.scdn.co/image/ab6761610000e5eb4293385d324db8558179afd9",
+ "height": 640,
+ "width": 640
+ },
+ {
+ "url": "https://i.scdn.co/image/ab676161000051744293385d324db8558179afd9",
+ "height": 320,
+ "width": 320
+ },
+ {
+ "url": "https://i.scdn.co/image/ab6761610000f1784293385d324db8558179afd9",
+ "height": 160,
+ "width": 160
+ }
+ ]
+}
+
+const artistExpectedFixtureAppearsOn = {
+ id: "3TVXtAsR1Inumwj472S9r4",
+ name: "Drake",
+ image: "https://i.scdn.co/image/ab6761610000e5eb4293385d324db8558179afd9",
+ popularity: 97,
+ genres: ["canadian hip hop","canadian pop","hip hop","pop rap","rap"],
+ spotify_url: "https://open.spotify.com/artist/3TVXtAsR1Inumwj472S9r4",
+ type: "artist",
+}
+
+
+/* Album Raw */
+
+const songsRawAlbumArtist = {
+ items: [
+ {
+ album_type: 'album',
+ total_tracks: 34,
+ popularity: 50, // rentre a la main
+ external_urls: {
+ spotify: "https://open.spotify.com/album/57TzZhbqvYoUBzJSVKFVlG"
+ },
+ id: "57TzZhbqvYoUBzJSVKFVlG",
+ images: [
+ {
+ "height": 640,
+ "url": "https://i.scdn.co/image/ab67616d0000b273822e06488f98e53e8743ff6b",
+ "width": 640
+ },
+ {
+ "height": 300,
+ "url": "https://i.scdn.co/image/ab67616d00001e02822e06488f98e53e8743ff6b",
+ "width": 300
+ },
+ {
+ "height": 64,
+ "url": "https://i.scdn.co/image/ab67616d00004851822e06488f98e53e8743ff6b",
+ "width": 64
+ }
+ ],
+ name: "Thriller 40",
+ release_date: "2022-11-18",
+ artists: [
+ artistFixture
+ ],
+ album_group: "album"
+ }
+ ]
+}
+
+/* Expected Album Raw */
+
+const expectedAlbumArtist = [
+ {
+ id: "57TzZhbqvYoUBzJSVKFVlG",
+ total_tracks: 34,
+ name: "Thriller 40",
+ popularity: 50, // rentre a la main
+ release_date: "2022-11-18",
+ spotify_url: "https://open.spotify.com/album/57TzZhbqvYoUBzJSVKFVlG",
+ image: "https://i.scdn.co/image/ab67616d0000b273822e06488f98e53e8743ff6b",
+ artists: [
+ artistExpectedFixture
+ ],
+ tracks: undefined,
+ genres: undefined,
+ type: "album"
+ }
+]
+
+
+
+/* Single Raw */
+
+const songsRawSingleArtist = {
+ items: [
+ {
+ album_type: 'single',
+ total_tracks: 1,
+ popularity: 50, // rentre a la main
+ external_urls: {
+ spotify: "https://open.spotify.com/album/6ST7naJFCe9iBeOleU5Ccu"
+ },
+ id: "6ST7naJFCe9iBeOleU5Ccu",
+ images: [
+ {
+ "height": 640,
+ "url": "https://i.scdn.co/image/ab67616d0000b2739e9ceac980e4b6b59a766f8b",
+ "width": 640
+ },
+ {
+ "height": 300,
+ "url": "https://i.scdn.co/image/ab67616d00001e029e9ceac980e4b6b59a766f8b",
+ "width": 300
+ },
+ {
+ "height": 64,
+ "url": "https://i.scdn.co/image/ab67616d000048519e9ceac980e4b6b59a766f8b",
+ "width": 64
+ }
+ ],
+ name: "Michael Jackson x Mark Ronson: Diamonds are Invincible",
+ release_date: "2018-08-29",
+ artists: [
+ artistFixture
+ ],
+ album_group: "single"
+ }
+ ]
+}
+
+/* Expected Single Raw */
+
+const expectedSingleArtist = [
+ {
+ id: "6ST7naJFCe9iBeOleU5Ccu",
+ total_tracks: 1,
+ name: "Michael Jackson x Mark Ronson: Diamonds are Invincible",
+ popularity: 50, // rentre a la main
+ release_date: "2018-08-29",
+ spotify_url: "https://open.spotify.com/album/6ST7naJFCe9iBeOleU5Ccu",
+ image: "https://i.scdn.co/image/ab67616d0000b2739e9ceac980e4b6b59a766f8b",
+ artists: [
+ artistExpectedFixture
+ ],
+ tracks: undefined,
+ genres: undefined,
+ type: "single"
+ }
+]
+
+
+/* Compilation Raw */
+
+const songsRawCompilationArtist = {
+ items: [
+ {
+ album_type: 'compilation',
+ total_tracks: 14,
+ popularity: 50, // rentre a la main
+ external_urls: {
+ spotify: "https://open.spotify.com/album/2X8UOIkZQdcz2Hi5Ynt2uk"
+ },
+ id: "2X8UOIkZQdcz2Hi5Ynt2uk",
+ images: [
+ {
+ "height": 640,
+ "url": "https://i.scdn.co/image/ab67616d0000b273cde37cfdee48dc0eae1e2ab8",
+ "width": 640
+ },
+ {
+ "height": 300,
+ "url": "https://i.scdn.co/image/ab67616d00001e02cde37cfdee48dc0eae1e2ab8",
+ "width": 300
+ },
+ {
+ "height": 64,
+ "url": "https://i.scdn.co/image/ab67616d00004851cde37cfdee48dc0eae1e2ab8",
+ "width": 64
+ }
+ ],
+ name: "Scream",
+ release_date: "2017-09-27",
+ artists: [
+ artistFixture
+ ],
+ album_group: "compilation"
+ }
+ ]
+}
+
+/* Expected Compilation Raw */
+
+const expectedCompilationArtist = [
+ {
+ id: "2X8UOIkZQdcz2Hi5Ynt2uk",
+ total_tracks: 14,
+ name: "Scream",
+ popularity: 50, // rentre a la main
+ release_date: "2017-09-27", //fait
+ spotify_url: "https://open.spotify.com/album/2X8UOIkZQdcz2Hi5Ynt2uk",
+ image: "https://i.scdn.co/image/ab67616d0000b273cde37cfdee48dc0eae1e2ab8",
+ artists: [
+ artistExpectedFixture
+ ],
+ tracks: undefined,
+ genres: undefined,
+ type: "compilation"
+ }
+]
+
+
+
+/* appears_on Raw */
+
+const songsRawAppearsOnArtist = {
+ items: [
+ {
+ album_type: 'album',
+ total_tracks: 25,
+ popularity: 50, // rentre a la main
+ external_urls: {
+ spotify: "https://open.spotify.com/album/1ATL5GLyefJaxhQzSPVrLX"
+ },
+ id: "1ATL5GLyefJaxhQzSPVrLX",
+ images: [
+ {
+ "height": 640,
+ "url": "https://i.scdn.co/image/ab67616d0000b273f907de96b9a4fbc04accc0d5",
+ "width": 640
+ },
+ {
+ "height": 300,
+ "url": "https://i.scdn.co/image/ab67616d00001e02f907de96b9a4fbc04accc0d5",
+ "width": 300
+ },
+ {
+ "height": 64,
+ "url": "https://i.scdn.co/image/ab67616d00004851f907de96b9a4fbc04accc0d5",
+ "width": 64
+ }
+ ],
+ name: "Scorpion",
+ release_date: "2018-06-29",
+ artists: [
+ artistFixtureAppearsOn
+ ],
+ album_group: "appears_on"
+ }
+ ]
+}
+
+/* Expected appears_on Raw */
+
+const expectedAppearsOnArtist = [
+ {
+ id: "1ATL5GLyefJaxhQzSPVrLX",
+ total_tracks: 25,
+ name: "Scorpion",
+ popularity: 50, // rentre a la main
+ release_date: "2018-06-29", //fait
+ spotify_url: "https://open.spotify.com/album/1ATL5GLyefJaxhQzSPVrLX",
+ image: "https://i.scdn.co/image/ab67616d0000b273f907de96b9a4fbc04accc0d5",
+ artists: [
+ artistExpectedFixtureAppearsOn
+ ],
+ tracks: undefined,
+ genres: undefined,
+ type: "appears_on"
+ }
+]
+
+
+
+
+module.exports = {
+ songsRawAlbumArtist,
+ expectedAlbumArtist,
+ songsRawSingleArtist,
+ expectedSingleArtist,
+ songsRawCompilationArtist,
+ expectedCompilationArtist,
+ songsRawAppearsOnArtist,
+ expectedAppearsOnArtist
+}
\ No newline at end of file
diff --git a/test/unit/interfaces/serializers/fixtures/artistFixture.js b/test/unit/interfaces/serializers/fixtures/artistFixture.js
index ec49a4a..c2532f2 100644
--- a/test/unit/interfaces/serializers/fixtures/artistFixture.js
+++ b/test/unit/interfaces/serializers/fixtures/artistFixture.js
@@ -28,23 +28,7 @@ const expectedFixture = {
id: "4FpJcNgOvIpSBeJgRg3OfN",
name: "Orelsan",
- images: [
- {
- url: "https://i.scdn.co/image/ab67616d0000b2730b2e3999b189fa2a8a6a752f",
- height: 640,
- width: 640
- },
- {
- url: "https://i.scdn.co/image/ab67616d00001e020b2e3999b189fa2a8a6a752f",
- height: 300,
- width: 300
- },
- {
- url: "https://i.scdn.co/image/ab67616d000048510b2e3999b189fa2a8a6a752f",
- height: 64,
- width: 64
- }
- ],
+ image: "https://i.scdn.co/image/ab67616d0000b2730b2e3999b189fa2a8a6a752f",
popularity: 10,
genres:['rock','funk'],
spotify_url: "https://open.spotify.com/artist/4FpJcNgOvIpSBeJgRg3OfN",