From 7366c27eb18cd70f03e521467a468abc16149ce9 Mon Sep 17 00:00:00 2001
From: John Labbate
Date: Mon, 8 Apr 2024 10:05:55 -0400
Subject: [PATCH 01/24] update agencie stat to 250 from 560.
---
training-front-end/src/content/training_fleet_pc/lesson01.mdx | 2 +-
training-front-end/src/content/training_purchase/lesson01.mdx | 2 +-
.../src/content/training_purchase_pc/lesson01.mdx | 2 +-
training-front-end/src/content/training_travel/lesson01.mdx | 2 +-
training-front-end/src/content/training_travel_pc/lesson01.mdx | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/training-front-end/src/content/training_fleet_pc/lesson01.mdx b/training-front-end/src/content/training_fleet_pc/lesson01.mdx
index d2b45636..bcecab4e 100644
--- a/training-front-end/src/content/training_fleet_pc/lesson01.mdx
+++ b/training-front-end/src/content/training_fleet_pc/lesson01.mdx
@@ -10,7 +10,7 @@ tags:
import Image from "../../components/Image.astro"
## What is the GSA SmartPay® program?
-Established in 1998, the GSA SmartPay program is the world’s largest government charge card and commercial payment solutions program, providing services to more than 560 federal agencies/organizations and Native American tribal governments with 6.5 million total accounts. GSA SmartPay payment solutions enable authorized government employees to make purchases on behalf of the federal government in support of their agency’s mission. The GSA SmartPay program includes the following business lines:
+Established in 1998, the GSA SmartPay program is the world’s largest government charge card and commercial payment solutions program, providing services to more than 250 federal agencies/organizations and Native American tribal governments with 6.5 million total accounts. GSA SmartPay payment solutions enable authorized government employees to make purchases on behalf of the federal government in support of their agency’s mission. The GSA SmartPay program includes the following business lines:
- GSA SmartPay Purchase.
- GSA SmartPay Travel.
- GSA SmartPay Fleet.
diff --git a/training-front-end/src/content/training_purchase/lesson01.mdx b/training-front-end/src/content/training_purchase/lesson01.mdx
index 0d6870c9..ebf31390 100644
--- a/training-front-end/src/content/training_purchase/lesson01.mdx
+++ b/training-front-end/src/content/training_purchase/lesson01.mdx
@@ -11,7 +11,7 @@ tags:
import Image from "../../components/Image.astro"
## What is the GSA SmartPay® program?
-Established in 1998, the GSA SmartPay program is the world’s largest government charge card and commercial payment solutions program, providing services to more than 560 federal agencies/organizations and Native American tribal governments with 6.5 million total accounts. GSA SmartPay payment solutions enable authorized government employees to make purchases on behalf of the federal government in support of their agency’s mission. The GSA SmartPay program includes the following business lines:
+Established in 1998, the GSA SmartPay program is the world’s largest government charge card and commercial payment solutions program, providing services to more than 250 federal agencies/organizations and Native American tribal governments with 6.5 million total accounts. GSA SmartPay payment solutions enable authorized government employees to make purchases on behalf of the federal government in support of their agency’s mission. The GSA SmartPay program includes the following business lines:
- GSA SmartPay Purchase.
- GSA SmartPay Travel.
- GSA SmartPay Fleet.
diff --git a/training-front-end/src/content/training_purchase_pc/lesson01.mdx b/training-front-end/src/content/training_purchase_pc/lesson01.mdx
index 49945977..02f3cc70 100644
--- a/training-front-end/src/content/training_purchase_pc/lesson01.mdx
+++ b/training-front-end/src/content/training_purchase_pc/lesson01.mdx
@@ -10,7 +10,7 @@ tags:
import Image from "../../components/Image.astro"
## What is the GSA SmartPay® program?
-Established in 1998, the GSA SmartPay program is the world’s largest government charge card and commercial payment solutions program, providing services to more than 560 federal agencies/organizations and Native American tribal governments with 6.5 million total accounts. GSA SmartPay payment solutions enable authorized government employees to make purchases on behalf of the federal government in support of their agency’s mission. The GSA SmartPay program includes the following business lines:
+Established in 1998, the GSA SmartPay program is the world’s largest government charge card and commercial payment solutions program, providing services to more than 250 federal agencies/organizations and Native American tribal governments with 6.5 million total accounts. GSA SmartPay payment solutions enable authorized government employees to make purchases on behalf of the federal government in support of their agency’s mission. The GSA SmartPay program includes the following business lines:
- GSA SmartPay Purchase.
- GSA SmartPay Travel.
- GSA SmartPay Fleet.
diff --git a/training-front-end/src/content/training_travel/lesson01.mdx b/training-front-end/src/content/training_travel/lesson01.mdx
index 78a491fe..03d157fc 100644
--- a/training-front-end/src/content/training_travel/lesson01.mdx
+++ b/training-front-end/src/content/training_travel/lesson01.mdx
@@ -12,7 +12,7 @@ import Image from "../../components/Image.astro"
## What is the GSA SmartPay® program?
-Established in 1998, the GSA SmartPay program is the world’s largest government charge card and commercial payment solutions program, providing services to more than 560 federal agencies/organizations and Native American tribal governments with 6.5 million total accounts. GSA SmartPay payment solutions enable authorized government employees to make purchases on behalf of the federal government in support of their agency’s mission. The GSA SmartPay program includes the following business lines:
+Established in 1998, the GSA SmartPay program is the world’s largest government charge card and commercial payment solutions program, providing services to more than 250 federal agencies/organizations and Native American tribal governments with 6.5 million total accounts. GSA SmartPay payment solutions enable authorized government employees to make purchases on behalf of the federal government in support of their agency’s mission. The GSA SmartPay program includes the following business lines:
- GSA SmartPay Purchase.
- GSA SmartPay Travel.
- GSA SmartPay Fleet.
diff --git a/training-front-end/src/content/training_travel_pc/lesson01.mdx b/training-front-end/src/content/training_travel_pc/lesson01.mdx
index a36e20f5..31043124 100644
--- a/training-front-end/src/content/training_travel_pc/lesson01.mdx
+++ b/training-front-end/src/content/training_travel_pc/lesson01.mdx
@@ -11,7 +11,7 @@ import Image from "../../components/Image.astro"
## What is the GSA SmartPay® program?
-Established in 1998, the GSA SmartPay program is the world’s largest government charge card and commercial payment solutions program, providing services to more than 560 federal agencies/organizations and Native American tribal governments with 6.5 million total accounts. GSA SmartPay payment solutions enable authorized government employees to make purchases on behalf of the federal government in support of their agency’s mission. The GSA SmartPay program includes the following business lines:
+Established in 1998, the GSA SmartPay program is the world’s largest government charge card and commercial payment solutions program, providing services to more than 250 federal agencies/organizations and Native American tribal governments with 6.5 million total accounts. GSA SmartPay payment solutions enable authorized government employees to make purchases on behalf of the federal government in support of their agency’s mission. The GSA SmartPay program includes the following business lines:
- GSA SmartPay Purchase.
- GSA SmartPay Travel.
- GSA SmartPay Fleet.
From cd241c5c6eece4df4cfa73cff1c4cda7bcca9972 Mon Sep 17 00:00:00 2001
From: John Labbate
Date: Wed, 10 Apr 2024 10:50:29 -0400
Subject: [PATCH 02/24] wip testing optional params in login destination.
---
.../src/components/GspcRegistration.vue | 103 ++++++++++++++++++
.../src/components/LoginlessFlow.vue | 7 +-
training/api/api_v1/loginless_flow.py | 3 +-
training/schemas/temp_user.py | 1 +
4 files changed, 112 insertions(+), 2 deletions(-)
create mode 100644 training-front-end/src/components/GspcRegistration.vue
diff --git a/training-front-end/src/components/GspcRegistration.vue b/training-front-end/src/components/GspcRegistration.vue
new file mode 100644
index 00000000..6e4d9c81
--- /dev/null
+++ b/training-front-end/src/components/GspcRegistration.vue
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+ {{ error.message }}
+
+
+
+ …Loading
+
+
+
+ GSPC Registration
+ Enter your email address to login. You'll receive an email with an access link.
+
+
+
+ Welcome!
+ Before you can register for GSPC, you'll need to create and complete your profile.
+
+
+ GSPC Placeholder
+ logged in
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/training-front-end/src/components/LoginlessFlow.vue b/training-front-end/src/components/LoginlessFlow.vue
index fed0a8af..84395f09 100644
--- a/training-front-end/src/components/LoginlessFlow.vue
+++ b/training-front-end/src/components/LoginlessFlow.vue
@@ -46,6 +46,11 @@
'linkDestinationText': {
type: String,
required: true
+ },
+ 'parameters': {
+ type: String,
+ required: false,
+ default: ""
}
})
@@ -161,7 +166,7 @@
headers: { 'Content-Type': 'application/json'},
body: JSON.stringify({
user: user_data,
- dest: {page_id: props.pageId, title: props.title}
+ dest: {page_id: props.pageId, parameters: props.parameters, title: props.title}
})
})
} catch (err) {
diff --git a/training/api/api_v1/loginless_flow.py b/training/api/api_v1/loginless_flow.py
index 1f00ff65..af03d3d0 100644
--- a/training/api/api_v1/loginless_flow.py
+++ b/training/api/api_v1/loginless_flow.py
@@ -106,7 +106,8 @@ def send_link(
detail="Server Error"
)
path = page_id_lookup[dest.page_id]['path']
- url = f"{settings.BASE_URL}{path}?t={token}"
+ parameters = f"t={token}" if not dest.parameters else f"{dest.parameters}&t={token}"
+ url = f"{settings.BASE_URL}{path}?{parameters}"
try:
send_email(to_email=user.email, name=user.name, link=url, training_title=dest.title)
logging.info(f"Sent confirmation email to {user.email} for {path}")
diff --git a/training/schemas/temp_user.py b/training/schemas/temp_user.py
index b46b5dc8..f9117bf7 100644
--- a/training/schemas/temp_user.py
+++ b/training/schemas/temp_user.py
@@ -40,4 +40,5 @@ class WebDestination(BaseModel):
after the loginless flow completes
'''
page_id: str
+ parameters: str
title: str
From f49f4db8c59085167419950e528898da285033b8 Mon Sep 17 00:00:00 2001
From: John Labbate
Date: Fri, 12 Apr 2024 15:11:37 -0400
Subject: [PATCH 03/24] Create placeholder gspc registration page and place it
behind login. Also allow for params to be passed into the login redirect.
---
.vscode/settings.json | 9 ++++
.../src/components/GspcRegistration.vue | 41 +++++--------------
.../src/components/LoginlessFlow.vue | 4 +-
.../src/components/QuizIndex.vue | 2 +-
.../__tests__/GspcRegistration.spec.js | 29 +++++++++++++
.../src/pages/gspc_registration/index.astro | 17 ++++++++
training/api/api_v1/gspc.py | 9 ++--
training/api/api_v1/loginless_flow.py | 9 ++--
training/api/email.py | 3 ++
training/tests/test_api_loginless_flow.py | 40 ++++++++++++++----
10 files changed, 113 insertions(+), 50 deletions(-)
create mode 100644 training-front-end/src/components/__tests__/GspcRegistration.spec.js
create mode 100644 training-front-end/src/pages/gspc_registration/index.astro
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 6e00fa4e..21d45c41 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -15,5 +15,14 @@
"python.testing.unittestEnabled": false,
"python.testing.pytestArgs": [
"training"
+ ],
+ "cSpell.words": [
+ "fastapi",
+ "GSPC",
+ "Loginless",
+ "nanostores",
+ "pydantic",
+ "USWDS",
+ "Vuelidate"
]
}
\ No newline at end of file
diff --git a/training-front-end/src/components/GspcRegistration.vue b/training-front-end/src/components/GspcRegistration.vue
index 6e4d9c81..1eb4b12c 100644
--- a/training-front-end/src/components/GspcRegistration.vue
+++ b/training-front-end/src/components/GspcRegistration.vue
@@ -1,42 +1,21 @@
+
+
+
+
+ Now that you’ve completed the training portion of the GSA SmartPay® {{ title }}, you are ready to take the quiz.
+
+
+ Once you’ve successfully passed the quiz, your certificate will be displayed. You can print the certificate or save it as a PDF.
+
+
+ Note: Your quiz progress will not be saved if you navigate away.
+
+
+ Continue to verify coursework and experience
+
+
+
+
+
+
+
+
+ Submit quiz
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/training-front-end/src/components/GspcRegistration.vue b/training-front-end/src/components/GspcRegistration.vue
index eb2b47da..c76cebc3 100644
--- a/training-front-end/src/components/GspcRegistration.vue
+++ b/training-front-end/src/components/GspcRegistration.vue
@@ -1,24 +1,28 @@
@@ -55,23 +94,25 @@
page-id="gspc_registration"
title="gspc_registration"
:header="header"
- link-destination-text="GSPC Registration"
+ link-destination-text="the GSA SmartPay Program Certification (GSPCS)"
:parameters="expirationDate"
@start-loading="startLoading"
@error="setError"
>
- GSPC Registration
- Enter your email address to login. You'll receive an email with an access link.
+ Verify GSPC coursework and experience
+ Enter your email address to get access to verify your coursework and experience to receive your GSA SmartPay Program Certification (GSPC). You'll receive an email with an access link.
Welcome!
- Before you can register for GSPC, you'll need to create and complete your profile.
+ Before verifying your GSPC coursework and experience, you'll need to create and complete your profile.
- GSPC Placeholder
- logged in
+
diff --git a/training/api/api_v1/gspc.py b/training/api/api_v1/gspc.py
index 75b9655b..ae6709a2 100644
--- a/training/api/api_v1/gspc.py
+++ b/training/api/api_v1/gspc.py
@@ -1,11 +1,15 @@
+from typing import Any
import logging
from fastapi import APIRouter, status, HTTPException, Depends
-from training.schemas.gspc_invite import GspcInvite
+from training.schemas import GspcInvite, GspcResult, GspcSubmission
+from training.services import GspcService
from training.repositories import GspcInviteRepository
-from training.api.deps import gspc_invite_repository
+from training.api.deps import gspc_invite_repository, gspc_service
from training.api.email import send_gspc_invite_email
from training.api.auth import RequireRole
from training.config import settings
+from training.api.auth import JWTUser
+
router = APIRouter()
@@ -42,3 +46,19 @@ async def gspc_admin_invite(
status_code=status.HTTP_400_BAD_REQUEST,
detail="emails or expiration date"
)
+
+
+@router.post(
+ "/submission",
+ response_model=GspcResult,
+ status_code=status.HTTP_201_CREATED
+)
+def submit_gspc_registration(
+ id: int,
+ submission: GspcSubmission,
+ gspc_service: GspcService = Depends(gspc_service),
+ user: dict[str, Any] = Depends(JWTUser())
+):
+ result = gspc_service.grade(quiz_id=id, user_id=user["id"], submission=submission)
+
+ return result
\ No newline at end of file
diff --git a/training/api/deps.py b/training/api/deps.py
index e5854276..78732668 100644
--- a/training/api/deps.py
+++ b/training/api/deps.py
@@ -1,7 +1,7 @@
from collections.abc import Generator
from fastapi import Depends
from training.repositories import AgencyRepository, UserRepository, QuizRepository, CertificateRepository, GspcInviteRepository
-from training.services import QuizService
+from training.services import QuizService, GspcService
from training.database import SessionLocal
from sqlalchemy.orm import Session
@@ -43,3 +43,7 @@ def certificate_repository(db: Session = Depends(db)) -> CertificateRepository:
def gspc_invite_repository(db: Session = Depends(db)) -> GspcInviteRepository:
return GspcInviteRepository(db)
+
+
+def gspc_service(db: Session = Depends(db)) -> GspcService:
+ return GspcService(db)
\ No newline at end of file
diff --git a/training/api/email.py b/training/api/email.py
index 6a5ddf6f..d2c5265a 100644
--- a/training/api/email.py
+++ b/training/api/email.py
@@ -36,7 +36,7 @@
GSPC recipients are also required to have a minimum of six (6) months of continuous, hands-on experience working with the GSA SmartPay program.
-Please do not share this link with others as it is unique to you.
+Please do not share this link with others.
$link
diff --git a/training/repositories/certificate.py b/training/repositories/certificate.py
index b05c6d31..12eacde2 100644
--- a/training/repositories/certificate.py
+++ b/training/repositories/certificate.py
@@ -1,6 +1,6 @@
from sqlalchemy.orm import Session
from training import models
-from training.schemas.user_cerificate import UserCertificate
+from training.schemas.user_certificate import UserCertificate
from .base import BaseRepository
diff --git a/training/schemas/__init__.py b/training/schemas/__init__.py
index ab426a90..6874a8b5 100644
--- a/training/schemas/__init__.py
+++ b/training/schemas/__init__.py
@@ -1,6 +1,9 @@
from .agency import Agency, AgencyCreate, AgencyWithBureaus
from .temp_user import TempUser, IncompleteTempUser, WebDestination
from .user import User, UserCreate, UserQuizCompletionReportData, UserSearchResult, UserJWT, UserUpdate
+from .gspc_invite import GspcInvite
+from .gspc_result import GspcResult
+from .gspc_submission import GspcSubmission
from .quiz_choice import QuizChoice, QuizChoiceCreate, QuizChoicePublic
from .quiz_question import QuizQuestion, QuizQuestionCreate, QuizQuestionPublic, QuizQuestionType
from .quiz_content import QuizContent, QuizContentCreate, QuizContentPublic
@@ -8,7 +11,7 @@
from .quiz_submission import QuizSubmission
from .quiz_grade import QuizGrade
from .quiz_completion import QuizCompletion, QuizCompletionCreate
-from .user_cerificate import UserCertificate
+from .user_certificate import UserCertificate
from .user_x_role import UserXRole
from .report_user_x_agency import ReportUserXAgency
from .role import Role, RoleCreate
diff --git a/training/schemas/gspc_result.py b/training/schemas/gspc_result.py
new file mode 100644
index 00000000..5a43f147
--- /dev/null
+++ b/training/schemas/gspc_result.py
@@ -0,0 +1,5 @@
+from pydantic import BaseModel
+
+
+class GspcResult(BaseModel):
+ passed: bool
diff --git a/training/schemas/gspc_submission.py b/training/schemas/gspc_submission.py
new file mode 100644
index 00000000..58733d82
--- /dev/null
+++ b/training/schemas/gspc_submission.py
@@ -0,0 +1,13 @@
+from pydantic import BaseModel
+
+
+class QuizSubmissionQuestion(BaseModel):
+ question_id: int
+ question: str
+ response_ids: list[int]
+ response: list[str]
+ correct: bool
+
+
+class GspcSubmission(BaseModel):
+ responses: list[QuizSubmissionQuestion]
diff --git a/training/schemas/user_cerificate.py b/training/schemas/user_certificate.py
similarity index 100%
rename from training/schemas/user_cerificate.py
rename to training/schemas/user_certificate.py
diff --git a/training/services/__init__.py b/training/services/__init__.py
index 30894c41..f3974219 100644
--- a/training/services/__init__.py
+++ b/training/services/__init__.py
@@ -1,2 +1,3 @@
from .certificate import Certificate
+from .gspc import GspcService
from .quiz import QuizService
diff --git a/training/services/gspc.py b/training/services/gspc.py
new file mode 100644
index 00000000..5d0047e3
--- /dev/null
+++ b/training/services/gspc.py
@@ -0,0 +1,28 @@
+from training.schemas import GspcSubmission, GspcResult
+from sqlalchemy.orm import Session
+
+
+class GspcService():
+ def __init__(self, db: Session):
+ pass
+
+ def grade(self, user_id: int, submission: GspcSubmission) -> GspcResult:
+ """
+ Grades a GspcSubmission submitted by user. Sends congratulation email if user meets the criteria.
+ :param user_id: User ID
+ :param submission: Quiz submission object
+ :return: GspcResult model which includes the final result
+ """
+
+ passed = all(question.correct for question in submission.responses)
+
+ # Todo
+ # - Save Submission
+ # - Generate and save cert
+ # - Send Email on pass
+
+ result = GspcResult(
+ passed=passed,
+ )
+
+ return result
From ff6ad09c7f3d5501c6c26d29d640d0623162ebeb Mon Sep 17 00:00:00 2001
From: John Labbate
Date: Tue, 30 Apr 2024 08:48:50 -0400
Subject: [PATCH 09/24] Finished registration workflow pending tests.
---
.../src/components/GspcQuestion.vue | 54 +++++++++++++++++
.../src/components/GspcQuestions.vue | 20 ++++---
.../src/components/GspcRegistration.vue | 60 ++++++++++++++-----
.../src/components/LoginlessFlow.vue | 5 +-
training/api/api_v1/gspc.py | 6 +-
training/schemas/gspc_submission.py | 9 +--
6 files changed, 120 insertions(+), 34 deletions(-)
create mode 100644 training-front-end/src/components/GspcQuestion.vue
diff --git a/training-front-end/src/components/GspcQuestion.vue b/training-front-end/src/components/GspcQuestion.vue
new file mode 100644
index 00000000..544102e0
--- /dev/null
+++ b/training-front-end/src/components/GspcQuestion.vue
@@ -0,0 +1,54 @@
+
+
+
+
+ {{ question.text }}
+
+
+
+ {{ text }}
+
+
+
\ No newline at end of file
diff --git a/training-front-end/src/components/GspcQuestions.vue b/training-front-end/src/components/GspcQuestions.vue
index ffe4ef63..8bc87eed 100644
--- a/training-front-end/src/components/GspcQuestions.vue
+++ b/training-front-end/src/components/GspcQuestions.vue
@@ -1,7 +1,7 @@
@@ -95,7 +104,7 @@
title="gspc_registration"
:header="header"
link-destination-text="the GSA SmartPay Program Certification (GSPCS)"
- :parameters="expirationDate"
+ :parameters="redirectExpirationDateString"
@start-loading="startLoading"
@error="setError"
>
@@ -108,11 +117,30 @@
Welcome!
Before verifying your GSPC coursework and experience, you'll need to create and complete your profile.
-
-
+
+
Congratulations You Earned Your GSA SmartPay® Program Certificate (GSPC)
+
You have met the requirements to earn a GSA SmartPay® Program Certificate (GSPC). Your certificate has been emailed to you. Or, you may download your certificate below.
+
+ Download your certificate
+
+
+
Return to the GSA SmartPay Training Home Page
+
+
+
You Don't Meet the Requirements for GSA SmartPay® Program Certification (GSPC)
+
Once you have met the coursework and experience requirement of six months of continuous, hands-on experience working with the GSA SmartPay program please return to the link in your email to reapply.
+
If you have any questions ,please reference Smart Bulletin No. 022 or contact the GSPC Program Manager at smartpaygspc@gsa.com .
+
Return to the GSA SmartPay Training Home Page
+
+
+
+
diff --git a/training-front-end/src/components/LoginlessFlow.vue b/training-front-end/src/components/LoginlessFlow.vue
index ad90944a..8c746aa8 100644
--- a/training-front-end/src/components/LoginlessFlow.vue
+++ b/training-front-end/src/components/LoginlessFlow.vue
@@ -118,7 +118,10 @@
function clearToken() {
const url = new URL(window.location);
- url.search = ''
+ //remove token from url
+ const params = new URLSearchParams(url.search);
+ params.delete('t')
+ url.search = params
history.replaceState({}, '', url)
}
diff --git a/training/api/api_v1/gspc.py b/training/api/api_v1/gspc.py
index ae6709a2..a6ae43e6 100644
--- a/training/api/api_v1/gspc.py
+++ b/training/api/api_v1/gspc.py
@@ -49,16 +49,14 @@ async def gspc_admin_invite(
@router.post(
- "/submission",
+ "/gspc/submission",
response_model=GspcResult,
status_code=status.HTTP_201_CREATED
)
def submit_gspc_registration(
- id: int,
submission: GspcSubmission,
gspc_service: GspcService = Depends(gspc_service),
user: dict[str, Any] = Depends(JWTUser())
):
- result = gspc_service.grade(quiz_id=id, user_id=user["id"], submission=submission)
-
+ result = gspc_service.grade(user_id=user["id"], submission=submission)
return result
\ No newline at end of file
diff --git a/training/schemas/gspc_submission.py b/training/schemas/gspc_submission.py
index 58733d82..7e90aff4 100644
--- a/training/schemas/gspc_submission.py
+++ b/training/schemas/gspc_submission.py
@@ -1,13 +1,14 @@
from pydantic import BaseModel
-class QuizSubmissionQuestion(BaseModel):
+class GspcSubmissionQuestion(BaseModel):
question_id: int
question: str
- response_ids: list[int]
- response: list[str]
+ response_id: int
+ response: str
correct: bool
class GspcSubmission(BaseModel):
- responses: list[QuizSubmissionQuestion]
+ expiration_date: str
+ responses: list[GspcSubmissionQuestion]
From c5d6ebb051309269d8af64dab93250c023cfffcb Mon Sep 17 00:00:00 2001
From: John Labbate
Date: Tue, 30 Apr 2024 10:38:50 -0400
Subject: [PATCH 10/24] cleanup.
---
.../src/components/GspcRegistration.vue | 6 +--
.../components/__tests__/GspcQuestion.spec.js | 54 +++++++++++++++++++
2 files changed, 56 insertions(+), 4 deletions(-)
create mode 100644 training-front-end/src/components/__tests__/GspcQuestion.spec.js
diff --git a/training-front-end/src/components/GspcRegistration.vue b/training-front-end/src/components/GspcRegistration.vue
index 2e5b3852..7f89597b 100644
--- a/training-front-end/src/components/GspcRegistration.vue
+++ b/training-front-end/src/components/GspcRegistration.vue
@@ -34,7 +34,7 @@
}
function downloadCert(){
- console.log('todo')
+ //console.log('todo')
}
async function submitGspcRegistration(user_answers) {
@@ -66,10 +66,8 @@
setError(e)
}
var result = await res.json()
- console.log(result.passed)
if(result.passed){
certPassed.value = true
- console.log('certPassed ='+certPassed.value)
} else{
certFailed.value = true
}
@@ -126,7 +124,7 @@
>
Download your certificate
-
+
Return to the GSA SmartPay Training Home Page
diff --git a/training-front-end/src/components/__tests__/GspcQuestion.spec.js b/training-front-end/src/components/__tests__/GspcQuestion.spec.js
new file mode 100644
index 00000000..8c51ffed
--- /dev/null
+++ b/training-front-end/src/components/__tests__/GspcQuestion.spec.js
@@ -0,0 +1,54 @@
+import { describe, it, expect} from 'vitest'
+import { shallowMount } from '@vue/test-utils'
+import GspcQuestion from '@/components/GspcQuestion.vue'
+
+describe('GspcQuestion', () => {
+ // Sample question data for testing
+ const question = {
+ id: 0,
+ text: 'Sample question text',
+ type: 'MultipleChoiceSingleSelect',
+ choices: [
+ { id: 0, text: 'Option 1', correct: true },
+ { id: 1, text: 'Option 2', correct: false }
+ ]
+ }
+
+ // Sample user answer for testing
+ const userAnswer = 0 // Assuming the user selected the first choice
+
+ it('renders question text correctly', () => {
+ const wrapper = shallowMount(GspcQuestion, {
+ props: { question, selection: null }
+ })
+ expect(wrapper.text()).toContain(question.text)
+ })
+
+ it('renders choices correctly', () => {
+ const wrapper = shallowMount(GspcQuestion, {
+ props: { question, selection: null }
+ })
+ const choices = wrapper.findAll('input[type="radio"]')
+ expect(choices.length).toBe(question.choices.length)
+ question.choices.forEach((choice, index) => {
+ expect(choices[index].element.value).toBe(choice.id.toString())
+ expect(wrapper.text()).toContain(choice.text)
+ })
+ })
+
+ it('emits select_answer event with correct choice', async () => {
+ const wrapper = shallowMount(GspcQuestion, {
+ props: { question, selection: null }
+ })
+ await wrapper.find('input[value="0"]').setChecked()
+ expect(wrapper.emitted('select_answer')[0]).toEqual([0])
+ })
+
+ it('correctly highlights selected choice', async () => {
+ const wrapper = shallowMount(GspcQuestion, {
+ props: { question, selection: userAnswer }
+ })
+ const selectedChoice = wrapper.find(`input[value="${userAnswer}"]`)
+ expect(selectedChoice.element.checked).toBe(true)
+ })
+})
\ No newline at end of file
From 0478581db8a1bf0f6987685b1f5c335118ba234b Mon Sep 17 00:00:00 2001
From: John Labbate
Date: Tue, 30 Apr 2024 11:14:31 -0400
Subject: [PATCH 11/24] update vitest.
---
training-front-end/package-lock.json | 1948 +++++------------
training-front-end/package.json | 6 +-
.../components/__tests__/GspcQuestion.spec.js | 28 +-
.../__tests__/GspcRegistration.spec.js | 6 +-
4 files changed, 523 insertions(+), 1465 deletions(-)
diff --git a/training-front-end/package-lock.json b/training-front-end/package-lock.json
index be98be86..745d52b8 100644
--- a/training-front-end/package-lock.json
+++ b/training-front-end/package-lock.json
@@ -30,7 +30,7 @@
"@uswds/compile": "^1.1.0",
"@uswds/uswds": "^3.8.0",
"@vitejs/plugin-vue": "^4.1.0",
- "@vitest/coverage-c8": "^0.30.1",
+ "@vitest/coverage-v8": "^1.5.3",
"@vue/cli-plugin-eslint": "^5.0.8",
"@vue/test-utils": "^2.3.2",
"eslint": "^8.38.0",
@@ -41,7 +41,7 @@
"jsdom": "^21.1.1",
"pa11y-ci": "^3.0.1",
"start-server-and-test": "^2.0.3",
- "vitest": "^0.30.1"
+ "vitest": "^1.5.3"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@@ -528,9 +528,9 @@
}
},
"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==",
+ "version": "7.24.5",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz",
+ "integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==",
"bin": {
"parser": "bin/babel-parser.js"
},
@@ -713,7 +713,6 @@
"os": [
"aix"
],
- "peer": true,
"engines": {
"node": ">=12"
}
@@ -1352,6 +1351,18 @@
"node": ">=8"
}
},
+ "node_modules/@jest/schemas": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
+ "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
+ "dev": true,
+ "dependencies": {
+ "@sinclair/typebox": "^0.27.8"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.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",
@@ -1563,8 +1574,7 @@
"optional": true,
"os": [
"android"
- ],
- "peer": true
+ ]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.13.0",
@@ -1576,8 +1586,7 @@
"optional": true,
"os": [
"android"
- ],
- "peer": true
+ ]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.13.0",
@@ -1589,8 +1598,7 @@
"optional": true,
"os": [
"darwin"
- ],
- "peer": true
+ ]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.13.0",
@@ -1602,8 +1610,7 @@
"optional": true,
"os": [
"darwin"
- ],
- "peer": true
+ ]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.13.0",
@@ -1615,8 +1622,7 @@
"optional": true,
"os": [
"linux"
- ],
- "peer": true
+ ]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.13.0",
@@ -1628,8 +1634,7 @@
"optional": true,
"os": [
"linux"
- ],
- "peer": true
+ ]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.13.0",
@@ -1641,8 +1646,7 @@
"optional": true,
"os": [
"linux"
- ],
- "peer": true
+ ]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.13.0",
@@ -1654,8 +1658,7 @@
"optional": true,
"os": [
"linux"
- ],
- "peer": true
+ ]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.13.0",
@@ -1667,8 +1670,7 @@
"optional": true,
"os": [
"linux"
- ],
- "peer": true
+ ]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.13.0",
@@ -1680,8 +1682,7 @@
"optional": true,
"os": [
"linux"
- ],
- "peer": true
+ ]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.13.0",
@@ -1693,8 +1694,7 @@
"optional": true,
"os": [
"win32"
- ],
- "peer": true
+ ]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.13.0",
@@ -1706,8 +1706,7 @@
"optional": true,
"os": [
"win32"
- ],
- "peer": true
+ ]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.13.0",
@@ -1719,8 +1718,7 @@
"optional": true,
"os": [
"win32"
- ],
- "peer": true
+ ]
},
"node_modules/@sideway/address": {
"version": "4.1.5",
@@ -1743,6 +1741,12 @@
"integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==",
"dev": true
},
+ "node_modules/@sinclair/typebox": {
+ "version": "0.27.8",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
+ "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
+ "dev": true
+ },
"node_modules/@soda/friendly-errors-webpack-plugin": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.1.tgz",
@@ -1927,21 +1931,6 @@
"@types/node": "*"
}
},
- "node_modules/@types/chai": {
- "version": "4.3.12",
- "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.12.tgz",
- "integrity": "sha512-zNKDHG/1yxm8Il6uCCVsm+dRdEsJlFoDu73X17y09bId6UwoYww+vFBsAcRzl8knM1sab3Dp1VRikFQwDOtDDw==",
- "dev": true
- },
- "node_modules/@types/chai-subset": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.5.tgz",
- "integrity": "sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==",
- "dev": true,
- "dependencies": {
- "@types/chai": "*"
- }
- },
"node_modules/@types/connect": {
"version": "3.4.38",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
@@ -2073,12 +2062,6 @@
"@types/node": "*"
}
},
- "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
- },
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
@@ -2405,76 +2388,115 @@
"vue": "^3.0.0"
}
},
- "node_modules/@vitest/coverage-c8": {
- "version": "0.30.1",
- "resolved": "https://registry.npmjs.org/@vitest/coverage-c8/-/coverage-c8-0.30.1.tgz",
- "integrity": "sha512-/Wa3dtSuckpdngAmiCwowaEXXgJkqPrtfvrs9HTB9QoEfNbZWPu4E4cjEn4lJZb4qcGf4fxFtUA2f9DnDNAzBA==",
- "deprecated": "v8 coverage is moved to @vitest/coverage-v8 package",
+ "node_modules/@vitest/coverage-v8": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.5.3.tgz",
+ "integrity": "sha512-DPyGSu/fPHOJuPxzFSQoT4N/Fu/2aJfZRtEpEp8GI7NHsXBGE94CQ+pbEGBUMFjatsHPDJw/+TAF9r4ens2CNw==",
"dev": true,
"dependencies": {
- "c8": "^7.13.0",
+ "@ampproject/remapping": "^2.2.1",
+ "@bcoe/v8-coverage": "^0.2.3",
+ "debug": "^4.3.4",
+ "istanbul-lib-coverage": "^3.2.2",
+ "istanbul-lib-report": "^3.0.1",
+ "istanbul-lib-source-maps": "^5.0.4",
+ "istanbul-reports": "^3.1.6",
+ "magic-string": "^0.30.5",
+ "magicast": "^0.3.3",
"picocolors": "^1.0.0",
- "std-env": "^3.3.2"
+ "std-env": "^3.5.0",
+ "strip-literal": "^2.0.0",
+ "test-exclude": "^6.0.0"
},
"funding": {
- "url": "https://github.com/sponsors/antfu"
+ "url": "https://opencollective.com/vitest"
},
"peerDependencies": {
- "vitest": ">=0.30.0 <1"
+ "vitest": "1.5.3"
}
},
"node_modules/@vitest/expect": {
- "version": "0.30.1",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.30.1.tgz",
- "integrity": "sha512-c3kbEtN8XXJSeN81iDGq29bUzSjQhjES2WR3aColsS4lPGbivwLtas4DNUe0jD9gg/FYGIteqOenfU95EFituw==",
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.5.3.tgz",
+ "integrity": "sha512-y+waPz31pOFr3rD7vWTbwiLe5+MgsMm40jTZbQE8p8/qXyBX3CQsIXRx9XK12IbY7q/t5a5aM/ckt33b4PxK2g==",
"dev": true,
"dependencies": {
- "@vitest/spy": "0.30.1",
- "@vitest/utils": "0.30.1",
- "chai": "^4.3.7"
+ "@vitest/spy": "1.5.3",
+ "@vitest/utils": "1.5.3",
+ "chai": "^4.3.10"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
}
},
"node_modules/@vitest/runner": {
- "version": "0.30.1",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.30.1.tgz",
- "integrity": "sha512-W62kT/8i0TF1UBCNMRtRMOBWJKRnNyv9RrjIgdUryEe0wNpGZvvwPDLuzYdxvgSckzjp54DSpv1xUbv4BQ0qVA==",
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.5.3.tgz",
+ "integrity": "sha512-7PlfuReN8692IKQIdCxwir1AOaP5THfNkp0Uc4BKr2na+9lALNit7ub9l3/R7MP8aV61+mHKRGiqEKRIwu6iiQ==",
"dev": true,
"dependencies": {
- "@vitest/utils": "0.30.1",
- "concordance": "^5.0.4",
- "p-limit": "^4.0.0",
- "pathe": "^1.1.0"
+ "@vitest/utils": "1.5.3",
+ "p-limit": "^5.0.0",
+ "pathe": "^1.1.1"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/runner/node_modules/p-limit": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz",
+ "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==",
+ "dev": true,
+ "dependencies": {
+ "yocto-queue": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@vitest/snapshot": {
- "version": "0.30.1",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.30.1.tgz",
- "integrity": "sha512-fJZqKrE99zo27uoZA/azgWyWbFvM1rw2APS05yB0JaLwUIg9aUtvvnBf4q7JWhEcAHmSwbrxKFgyBUga6tq9Tw==",
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.5.3.tgz",
+ "integrity": "sha512-K3mvIsjyKYBhNIDujMD2gfQEzddLe51nNOAf45yKRt/QFJcUIeTQd2trRvv6M6oCBHNVnZwFWbQ4yj96ibiDsA==",
"dev": true,
"dependencies": {
- "magic-string": "^0.30.0",
- "pathe": "^1.1.0",
- "pretty-format": "^27.5.1"
+ "magic-string": "^0.30.5",
+ "pathe": "^1.1.1",
+ "pretty-format": "^29.7.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
}
},
"node_modules/@vitest/spy": {
- "version": "0.30.1",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.30.1.tgz",
- "integrity": "sha512-YfJeIf37GvTZe04ZKxzJfnNNuNSmTEGnla2OdL60C8od16f3zOfv9q9K0nNii0NfjDJRt/CVN/POuY5/zTS+BA==",
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.5.3.tgz",
+ "integrity": "sha512-Llj7Jgs6lbnL55WoshJUUacdJfjU2honvGcAJBxhra5TPEzTJH8ZuhI3p/JwqqfnTr4PmP7nDmOXP53MS7GJlg==",
"dev": true,
"dependencies": {
- "tinyspy": "^2.1.0"
+ "tinyspy": "^2.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
}
},
"node_modules/@vitest/utils": {
- "version": "0.30.1",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.30.1.tgz",
- "integrity": "sha512-/c8Xv2zUVc+rnNt84QF0Y0zkfxnaGhp87K2dYJMLtLOIckPzuxLVzAtFCicGFdB4NeBHNzTRr1tNn7rCtQcWFA==",
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.5.3.tgz",
+ "integrity": "sha512-rE9DTN1BRhzkzqNQO+kw8ZgfeEBCLXiHJwetk668shmNBpSagQxneT5eSqEBLP+cqSiAeecvQmbpFfdMyLcIQA==",
"dev": true,
"dependencies": {
- "concordance": "^5.0.4",
- "loupe": "^2.3.6",
- "pretty-format": "^27.5.1"
+ "diff-sequences": "^29.6.3",
+ "estree-walker": "^3.0.3",
+ "loupe": "^2.3.7",
+ "pretty-format": "^29.7.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
}
},
"node_modules/@vscode/emmet-helper": {
@@ -5374,12 +5396,6 @@
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
"dev": true
},
- "node_modules/blueimp-md5": {
- "version": "2.19.0",
- "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz",
- "integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==",
- "dev": true
- },
"node_modules/body-parser": {
"version": "1.20.2",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
@@ -5693,41 +5709,6 @@
"node": ">= 0.8"
}
},
- "node_modules/c8": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/c8/-/c8-7.14.0.tgz",
- "integrity": "sha512-i04rtkkcNcCf7zsQcSv/T9EbUn4RXQ6mropeMcjFOsQXQ0iGLAr/xT6TImQg4+U9hmNpN9XdvPkjUL1IzbgxJw==",
- "dev": true,
- "dependencies": {
- "@bcoe/v8-coverage": "^0.2.3",
- "@istanbuljs/schema": "^0.1.3",
- "find-up": "^5.0.0",
- "foreground-child": "^2.0.0",
- "istanbul-lib-coverage": "^3.2.0",
- "istanbul-lib-report": "^3.0.0",
- "istanbul-reports": "^3.1.4",
- "rimraf": "^3.0.2",
- "test-exclude": "^6.0.0",
- "v8-to-istanbul": "^9.0.0",
- "yargs": "^16.2.0",
- "yargs-parser": "^20.2.9"
- },
- "bin": {
- "c8": "bin/c8.js"
- },
- "engines": {
- "node": ">=10.12.0"
- }
- },
- "node_modules/c8/node_modules/yargs-parser": {
- "version": "20.2.9",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
- "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/cac": {
"version": "6.7.14",
"resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
@@ -6297,6 +6278,7 @@
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
"dev": true,
+ "peer": true,
"dependencies": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
@@ -6308,6 +6290,7 @@
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
+ "peer": true,
"dependencies": {
"color-convert": "^2.0.1"
},
@@ -6323,6 +6306,7 @@
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
+ "peer": true,
"dependencies": {
"color-name": "~1.1.4"
},
@@ -6334,13 +6318,15 @@
"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
+ "dev": true,
+ "peer": true
},
"node_modules/cliui/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,
+ "peer": true,
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
@@ -6603,56 +6589,10 @@
"typedarray": "^0.0.6"
}
},
- "node_modules/concordance": {
- "version": "5.0.4",
- "resolved": "https://registry.npmjs.org/concordance/-/concordance-5.0.4.tgz",
- "integrity": "sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==",
- "dev": true,
- "dependencies": {
- "date-time": "^3.1.0",
- "esutils": "^2.0.3",
- "fast-diff": "^1.2.0",
- "js-string-escape": "^1.0.1",
- "lodash": "^4.17.15",
- "md5-hex": "^3.0.1",
- "semver": "^7.3.2",
- "well-known-symbols": "^2.0.0"
- },
- "engines": {
- "node": ">=10.18.0 <11 || >=12.14.0 <13 || >=14"
- }
- },
- "node_modules/concordance/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==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/concordance/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==",
- "dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/concordance/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "node_modules/confbox": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz",
+ "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==",
"dev": true
},
"node_modules/config-chain": {
@@ -7279,18 +7219,6 @@
"node": ">=14"
}
},
- "node_modules/date-time": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz",
- "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==",
- "dev": true,
- "dependencies": {
- "time-zone": "^1.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/debounce": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
@@ -7703,6 +7631,15 @@
"node": ">=0.3.1"
}
},
+ "node_modules/diff-sequences": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
+ "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
+ "dev": true,
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
"node_modules/dir-glob": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -9468,12 +9405,6 @@
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
- "node_modules/fast-diff": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
- "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
- "dev": true
- },
"node_modules/fast-glob": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
@@ -9941,19 +9872,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/foreground-child": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
- "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==",
- "dev": true,
- "dependencies": {
- "cross-spawn": "^7.0.0",
- "signal-exit": "^3.0.2"
- },
- "engines": {
- "node": ">=8.0.0"
- }
- },
"node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
@@ -10136,6 +10054,7 @@
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true,
+ "peer": true,
"engines": {
"node": "6.* || 8.* || >= 10.*"
}
@@ -12770,6 +12689,20 @@
"node": ">=8"
}
},
+ "node_modules/istanbul-lib-source-maps": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.4.tgz",
+ "integrity": "sha512-wHOoEsNJTVltaJp8eVkm8w+GVkVNHT2YDYo53YdzQEL2gWm1hBX5cGFR9hQJtuGLebidVX7et3+dmDZrmclduw==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.23",
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/istanbul-reports": {
"version": "3.1.7",
"resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz",
@@ -12933,15 +12866,6 @@
"node": ">=0.6.0"
}
},
- "node_modules/js-string-escape": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz",
- "integrity": "sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==",
- "dev": true,
- "engines": {
- "node": ">= 0.8"
- }
- },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -13437,10 +13361,14 @@
}
},
"node_modules/local-pkg": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz",
- "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==",
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz",
+ "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==",
"dev": true,
+ "dependencies": {
+ "mlly": "^1.4.2",
+ "pkg-types": "^1.0.3"
+ },
"engines": {
"node": ">=14"
},
@@ -13776,6 +13704,17 @@
"node": ">=12"
}
},
+ "node_modules/magicast": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.4.tgz",
+ "integrity": "sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.24.4",
+ "@babel/types": "^7.24.0",
+ "source-map-js": "^1.2.0"
+ }
+ },
"node_modules/make-dir": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
@@ -14064,18 +14003,6 @@
"integrity": "sha512-c4vLwYWyl+Ji+U43eU/G5FwxWd4ZH0ePUsFs5y0uwD9HUEFBXUQ1zUUan+78IpRD+y4pUfG0nAzNM292K7ItvA==",
"dev": true
},
- "node_modules/md5-hex": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz",
- "integrity": "sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==",
- "dev": true,
- "dependencies": {
- "blueimp-md5": "^2.10.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/mdast-heading-id": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mdast-heading-id/-/mdast-heading-id-1.0.1.tgz",
@@ -19978,22 +19905,16 @@
}
},
"node_modules/pkg-types": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz",
- "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.0.tgz",
+ "integrity": "sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==",
"dev": true,
"dependencies": {
- "jsonc-parser": "^3.2.0",
- "mlly": "^1.2.0",
- "pathe": "^1.1.0"
+ "confbox": "^0.1.7",
+ "mlly": "^1.6.1",
+ "pathe": "^1.1.2"
}
},
- "node_modules/pkg-types/node_modules/jsonc-parser": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz",
- "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==",
- "dev": true
- },
"node_modules/plugin-error": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz",
@@ -20797,17 +20718,17 @@
}
},
"node_modules/pretty-format": {
- "version": "27.5.1",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
- "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
+ "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
"dev": true,
"dependencies": {
- "ansi-regex": "^5.0.1",
+ "@jest/schemas": "^29.6.3",
"ansi-styles": "^5.0.0",
- "react-is": "^17.0.1"
+ "react-is": "^18.0.0"
},
"engines": {
- "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/pretty-format/node_modules/ansi-styles": {
@@ -21150,9 +21071,9 @@
}
},
"node_modules/react-is": {
- "version": "17.0.2",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
- "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
"dev": true
},
"node_modules/read-pkg": {
@@ -22013,7 +21934,6 @@
"version": "4.13.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz",
"integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==",
- "peer": true,
"dependencies": {
"@types/estree": "1.0.5"
},
@@ -23062,9 +22982,9 @@
}
},
"node_modules/source-map-js": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
- "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
+ "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
"engines": {
"node": ">=0.10.0"
}
@@ -23718,17 +23638,23 @@
}
},
"node_modules/strip-literal": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz",
- "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz",
+ "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==",
"dev": true,
"dependencies": {
- "acorn": "^8.10.0"
+ "js-tokens": "^9.0.0"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
+ "node_modules/strip-literal/node_modules/js-tokens": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz",
+ "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==",
+ "dev": true
+ },
"node_modules/style-to-object": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz",
@@ -24240,15 +24166,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/time-zone": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz",
- "integrity": "sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/timers-ext": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz",
@@ -24266,9 +24183,9 @@
"dev": true
},
"node_modules/tinypool": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.4.0.tgz",
- "integrity": "sha512-2ksntHOKf893wSAH4z/+JbPpi92esw8Gn9N2deXX+B0EO92hexAVI9GIZZPx7P5aYo5KULfeOSt3kMOmSOy6uA==",
+ "version": "0.8.4",
+ "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz",
+ "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==",
"dev": true,
"engines": {
"node": ">=14.0.0"
@@ -24628,9 +24545,9 @@
}
},
"node_modules/ufo": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.4.0.tgz",
- "integrity": "sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ==",
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz",
+ "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==",
"dev": true
},
"node_modules/unbox-primitive": {
@@ -25093,20 +25010,6 @@
"node": ">=8"
}
},
- "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,
- "dependencies": {
- "@jridgewell/trace-mapping": "^0.3.12",
- "@types/istanbul-lib-coverage": "^2.0.1",
- "convert-source-map": "^2.0.0"
- },
- "engines": {
- "node": ">=10.12.0"
- }
- },
"node_modules/v8flags": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz",
@@ -25307,7 +25210,6 @@
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.1.6.tgz",
"integrity": "sha512-yYIAZs9nVfRJ/AiOLCA91zzhjsHUgMjB+EigzFb6W2XTLO8JixBCKCjvhKZaye+NKYHCrkv3Oh50dH9EdLU2RA==",
- "peer": true,
"dependencies": {
"esbuild": "^0.19.3",
"postcss": "^8.4.35",
@@ -25359,36 +25261,34 @@
}
},
"node_modules/vite-node": {
- "version": "0.30.1",
- "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.30.1.tgz",
- "integrity": "sha512-vTikpU/J7e6LU/8iM3dzBo8ZhEiKZEKRznEMm+mJh95XhWaPrJQraT/QsT2NWmuEf+zgAoMe64PKT7hfZ1Njmg==",
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.5.3.tgz",
+ "integrity": "sha512-axFo00qiCpU/JLd8N1gu9iEYL3xTbMbMrbe5nDp9GL0nb6gurIdZLkkFogZXWnE8Oyy5kfSLwNVIcVsnhE7lgQ==",
"dev": true,
"dependencies": {
"cac": "^6.7.14",
"debug": "^4.3.4",
- "mlly": "^1.2.0",
- "pathe": "^1.1.0",
+ "pathe": "^1.1.1",
"picocolors": "^1.0.0",
- "vite": "^3.0.0 || ^4.0.0"
+ "vite": "^5.0.0"
},
"bin": {
"vite-node": "vite-node.mjs"
},
"engines": {
- "node": ">=v14.18.0"
+ "node": "^18.0.0 || >=20.0.0"
},
"funding": {
- "url": "https://github.com/sponsors/antfu"
+ "url": "https://opencollective.com/vitest"
}
},
- "node_modules/vite-node/node_modules/@esbuild/android-arm": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
- "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
+ "node_modules/vite/node_modules/@esbuild/android-arm": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz",
+ "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==",
"cpu": [
"arm"
],
- "dev": true,
"optional": true,
"os": [
"android"
@@ -25397,14 +25297,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/android-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
- "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
+ "node_modules/vite/node_modules/@esbuild/android-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz",
+ "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==",
"cpu": [
"arm64"
],
- "dev": true,
"optional": true,
"os": [
"android"
@@ -25413,14 +25312,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/android-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
- "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
+ "node_modules/vite/node_modules/@esbuild/android-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz",
+ "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==",
"cpu": [
"x64"
],
- "dev": true,
"optional": true,
"os": [
"android"
@@ -25429,14 +25327,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/darwin-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
- "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
+ "node_modules/vite/node_modules/@esbuild/darwin-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz",
+ "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==",
"cpu": [
"arm64"
],
- "dev": true,
"optional": true,
"os": [
"darwin"
@@ -25445,14 +25342,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/darwin-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
- "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
+ "node_modules/vite/node_modules/@esbuild/darwin-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz",
+ "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==",
"cpu": [
"x64"
],
- "dev": true,
"optional": true,
"os": [
"darwin"
@@ -25461,14 +25357,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/freebsd-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
- "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
+ "node_modules/vite/node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz",
+ "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==",
"cpu": [
"arm64"
],
- "dev": true,
"optional": true,
"os": [
"freebsd"
@@ -25477,14 +25372,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/freebsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
- "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
+ "node_modules/vite/node_modules/@esbuild/freebsd-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz",
+ "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==",
"cpu": [
"x64"
],
- "dev": true,
"optional": true,
"os": [
"freebsd"
@@ -25493,14 +25387,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/linux-arm": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
- "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
+ "node_modules/vite/node_modules/@esbuild/linux-arm": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz",
+ "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==",
"cpu": [
"arm"
],
- "dev": true,
"optional": true,
"os": [
"linux"
@@ -25509,14 +25402,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/linux-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
- "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
+ "node_modules/vite/node_modules/@esbuild/linux-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz",
+ "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==",
"cpu": [
"arm64"
],
- "dev": true,
"optional": true,
"os": [
"linux"
@@ -25525,14 +25417,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/linux-ia32": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
- "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
+ "node_modules/vite/node_modules/@esbuild/linux-ia32": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz",
+ "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==",
"cpu": [
"ia32"
],
- "dev": true,
"optional": true,
"os": [
"linux"
@@ -25541,14 +25432,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/linux-loong64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
- "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
+ "node_modules/vite/node_modules/@esbuild/linux-loong64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz",
+ "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==",
"cpu": [
"loong64"
],
- "dev": true,
"optional": true,
"os": [
"linux"
@@ -25557,14 +25447,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/linux-mips64el": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
- "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
+ "node_modules/vite/node_modules/@esbuild/linux-mips64el": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz",
+ "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==",
"cpu": [
"mips64el"
],
- "dev": true,
"optional": true,
"os": [
"linux"
@@ -25573,14 +25462,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/linux-ppc64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
- "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
+ "node_modules/vite/node_modules/@esbuild/linux-ppc64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz",
+ "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==",
"cpu": [
"ppc64"
],
- "dev": true,
"optional": true,
"os": [
"linux"
@@ -25589,14 +25477,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/linux-riscv64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
- "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
+ "node_modules/vite/node_modules/@esbuild/linux-riscv64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz",
+ "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==",
"cpu": [
"riscv64"
],
- "dev": true,
"optional": true,
"os": [
"linux"
@@ -25605,14 +25492,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/linux-s390x": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
- "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
+ "node_modules/vite/node_modules/@esbuild/linux-s390x": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz",
+ "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==",
"cpu": [
"s390x"
],
- "dev": true,
"optional": true,
"os": [
"linux"
@@ -25621,14 +25507,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/linux-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
- "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
+ "node_modules/vite/node_modules/@esbuild/linux-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz",
+ "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==",
"cpu": [
"x64"
],
- "dev": true,
"optional": true,
"os": [
"linux"
@@ -25637,14 +25522,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/netbsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
- "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
+ "node_modules/vite/node_modules/@esbuild/netbsd-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz",
+ "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==",
"cpu": [
"x64"
],
- "dev": true,
"optional": true,
"os": [
"netbsd"
@@ -25653,14 +25537,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/openbsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
- "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
+ "node_modules/vite/node_modules/@esbuild/openbsd-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz",
+ "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==",
"cpu": [
"x64"
],
- "dev": true,
"optional": true,
"os": [
"openbsd"
@@ -25669,14 +25552,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/sunos-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
- "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
+ "node_modules/vite/node_modules/@esbuild/sunos-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz",
+ "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==",
"cpu": [
"x64"
],
- "dev": true,
"optional": true,
"os": [
"sunos"
@@ -25685,14 +25567,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/win32-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
- "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
+ "node_modules/vite/node_modules/@esbuild/win32-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz",
+ "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==",
"cpu": [
"arm64"
],
- "dev": true,
"optional": true,
"os": [
"win32"
@@ -25701,14 +25582,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/win32-ia32": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
- "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
+ "node_modules/vite/node_modules/@esbuild/win32-ia32": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz",
+ "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==",
"cpu": [
"ia32"
],
- "dev": true,
"optional": true,
"os": [
"win32"
@@ -25717,14 +25597,13 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/@esbuild/win32-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
- "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
+ "node_modules/vite/node_modules/@esbuild/win32-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz",
+ "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==",
"cpu": [
"x64"
],
- "dev": true,
"optional": true,
"os": [
"win32"
@@ -25733,11 +25612,10 @@
"node": ">=12"
}
},
- "node_modules/vite-node/node_modules/esbuild": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
- "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
- "dev": true,
+ "node_modules/vite/node_modules/esbuild": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz",
+ "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==",
"hasInstallScript": true,
"bin": {
"esbuild": "bin/esbuild"
@@ -25746,1078 +25624,256 @@
"node": ">=12"
},
"optionalDependencies": {
- "@esbuild/android-arm": "0.18.20",
- "@esbuild/android-arm64": "0.18.20",
- "@esbuild/android-x64": "0.18.20",
- "@esbuild/darwin-arm64": "0.18.20",
- "@esbuild/darwin-x64": "0.18.20",
- "@esbuild/freebsd-arm64": "0.18.20",
- "@esbuild/freebsd-x64": "0.18.20",
- "@esbuild/linux-arm": "0.18.20",
- "@esbuild/linux-arm64": "0.18.20",
- "@esbuild/linux-ia32": "0.18.20",
- "@esbuild/linux-loong64": "0.18.20",
- "@esbuild/linux-mips64el": "0.18.20",
- "@esbuild/linux-ppc64": "0.18.20",
- "@esbuild/linux-riscv64": "0.18.20",
- "@esbuild/linux-s390x": "0.18.20",
- "@esbuild/linux-x64": "0.18.20",
- "@esbuild/netbsd-x64": "0.18.20",
- "@esbuild/openbsd-x64": "0.18.20",
- "@esbuild/sunos-x64": "0.18.20",
- "@esbuild/win32-arm64": "0.18.20",
- "@esbuild/win32-ia32": "0.18.20",
- "@esbuild/win32-x64": "0.18.20"
+ "@esbuild/aix-ppc64": "0.19.12",
+ "@esbuild/android-arm": "0.19.12",
+ "@esbuild/android-arm64": "0.19.12",
+ "@esbuild/android-x64": "0.19.12",
+ "@esbuild/darwin-arm64": "0.19.12",
+ "@esbuild/darwin-x64": "0.19.12",
+ "@esbuild/freebsd-arm64": "0.19.12",
+ "@esbuild/freebsd-x64": "0.19.12",
+ "@esbuild/linux-arm": "0.19.12",
+ "@esbuild/linux-arm64": "0.19.12",
+ "@esbuild/linux-ia32": "0.19.12",
+ "@esbuild/linux-loong64": "0.19.12",
+ "@esbuild/linux-mips64el": "0.19.12",
+ "@esbuild/linux-ppc64": "0.19.12",
+ "@esbuild/linux-riscv64": "0.19.12",
+ "@esbuild/linux-s390x": "0.19.12",
+ "@esbuild/linux-x64": "0.19.12",
+ "@esbuild/netbsd-x64": "0.19.12",
+ "@esbuild/openbsd-x64": "0.19.12",
+ "@esbuild/sunos-x64": "0.19.12",
+ "@esbuild/win32-arm64": "0.19.12",
+ "@esbuild/win32-ia32": "0.19.12",
+ "@esbuild/win32-x64": "0.19.12"
}
},
- "node_modules/vite-node/node_modules/rollup": {
- "version": "3.29.4",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
- "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
- "dev": true,
- "bin": {
- "rollup": "dist/bin/rollup"
+ "node_modules/vite/node_modules/postcss": {
+ "version": "8.4.35",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz",
+ "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
},
"engines": {
- "node": ">=14.18.0",
- "npm": ">=8.0.0"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
+ "node": "^10 || ^12 || >=14"
}
},
- "node_modules/vite-node/node_modules/vite": {
- "version": "4.5.2",
- "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz",
- "integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==",
- "dev": true,
- "dependencies": {
- "esbuild": "^0.18.10",
- "postcss": "^8.4.27",
- "rollup": "^3.27.1"
- },
- "bin": {
- "vite": "bin/vite.js"
- },
- "engines": {
- "node": "^14.18.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/vitejs/vite?sponsor=1"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- },
+ "node_modules/vitefu": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz",
+ "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==",
"peerDependencies": {
- "@types/node": ">= 14",
- "less": "*",
- "lightningcss": "^1.21.0",
- "sass": "*",
- "stylus": "*",
- "sugarss": "*",
- "terser": "^5.4.0"
+ "vite": "^3.0.0 || ^4.0.0 || ^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "vite": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vitest": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.5.3.tgz",
+ "integrity": "sha512-2oM7nLXylw3mQlW6GXnRriw+7YvZFk/YNV8AxIC3Z3MfFbuziLGWP9GPxxu/7nRlXhqyxBikpamr+lEEj1sUEw==",
+ "dev": true,
+ "dependencies": {
+ "@vitest/expect": "1.5.3",
+ "@vitest/runner": "1.5.3",
+ "@vitest/snapshot": "1.5.3",
+ "@vitest/spy": "1.5.3",
+ "@vitest/utils": "1.5.3",
+ "acorn-walk": "^8.3.2",
+ "chai": "^4.3.10",
+ "debug": "^4.3.4",
+ "execa": "^8.0.1",
+ "local-pkg": "^0.5.0",
+ "magic-string": "^0.30.5",
+ "pathe": "^1.1.1",
+ "picocolors": "^1.0.0",
+ "std-env": "^3.5.0",
+ "strip-literal": "^2.0.0",
+ "tinybench": "^2.5.1",
+ "tinypool": "^0.8.3",
+ "vite": "^5.0.0",
+ "vite-node": "1.5.3",
+ "why-is-node-running": "^2.2.2"
+ },
+ "bin": {
+ "vitest": "vitest.mjs"
},
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- },
- "less": {
- "optional": true
- },
- "lightningcss": {
- "optional": true
- },
- "sass": {
- "optional": true
- },
- "stylus": {
- "optional": true
- },
- "sugarss": {
- "optional": true
- },
- "terser": {
- "optional": true
- }
- }
- },
- "node_modules/vite/node_modules/@esbuild/android-arm": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz",
- "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==",
- "cpu": [
- "arm"
- ],
- "optional": true,
- "os": [
- "android"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/android-arm64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz",
- "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==",
- "cpu": [
- "arm64"
- ],
- "optional": true,
- "os": [
- "android"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/android-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz",
- "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "android"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/darwin-arm64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz",
- "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==",
- "cpu": [
- "arm64"
- ],
- "optional": true,
- "os": [
- "darwin"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/darwin-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz",
- "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "darwin"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/freebsd-arm64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz",
- "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==",
- "cpu": [
- "arm64"
- ],
- "optional": true,
- "os": [
- "freebsd"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/freebsd-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz",
- "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "freebsd"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-arm": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz",
- "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==",
- "cpu": [
- "arm"
- ],
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-arm64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz",
- "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==",
- "cpu": [
- "arm64"
- ],
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-ia32": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz",
- "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==",
- "cpu": [
- "ia32"
- ],
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-loong64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz",
- "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==",
- "cpu": [
- "loong64"
- ],
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-mips64el": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz",
- "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==",
- "cpu": [
- "mips64el"
- ],
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-ppc64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz",
- "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==",
- "cpu": [
- "ppc64"
- ],
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-riscv64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz",
- "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==",
- "cpu": [
- "riscv64"
- ],
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-s390x": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz",
- "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==",
- "cpu": [
- "s390x"
- ],
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz",
- "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/netbsd-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz",
- "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "netbsd"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/openbsd-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz",
- "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "openbsd"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/sunos-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz",
- "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "sunos"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/win32-arm64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz",
- "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==",
- "cpu": [
- "arm64"
- ],
- "optional": true,
- "os": [
- "win32"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/win32-ia32": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz",
- "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==",
- "cpu": [
- "ia32"
- ],
- "optional": true,
- "os": [
- "win32"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/win32-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz",
- "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "win32"
- ],
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/esbuild": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz",
- "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==",
- "hasInstallScript": true,
- "peer": true,
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=12"
- },
- "optionalDependencies": {
- "@esbuild/aix-ppc64": "0.19.12",
- "@esbuild/android-arm": "0.19.12",
- "@esbuild/android-arm64": "0.19.12",
- "@esbuild/android-x64": "0.19.12",
- "@esbuild/darwin-arm64": "0.19.12",
- "@esbuild/darwin-x64": "0.19.12",
- "@esbuild/freebsd-arm64": "0.19.12",
- "@esbuild/freebsd-x64": "0.19.12",
- "@esbuild/linux-arm": "0.19.12",
- "@esbuild/linux-arm64": "0.19.12",
- "@esbuild/linux-ia32": "0.19.12",
- "@esbuild/linux-loong64": "0.19.12",
- "@esbuild/linux-mips64el": "0.19.12",
- "@esbuild/linux-ppc64": "0.19.12",
- "@esbuild/linux-riscv64": "0.19.12",
- "@esbuild/linux-s390x": "0.19.12",
- "@esbuild/linux-x64": "0.19.12",
- "@esbuild/netbsd-x64": "0.19.12",
- "@esbuild/openbsd-x64": "0.19.12",
- "@esbuild/sunos-x64": "0.19.12",
- "@esbuild/win32-arm64": "0.19.12",
- "@esbuild/win32-ia32": "0.19.12",
- "@esbuild/win32-x64": "0.19.12"
- }
- },
- "node_modules/vite/node_modules/postcss": {
- "version": "8.4.35",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz",
- "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "peer": true,
- "dependencies": {
- "nanoid": "^3.3.7",
- "picocolors": "^1.0.0",
- "source-map-js": "^1.0.2"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "node_modules/vitefu": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz",
- "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==",
- "peerDependencies": {
- "vite": "^3.0.0 || ^4.0.0 || ^5.0.0"
- },
- "peerDependenciesMeta": {
- "vite": {
- "optional": true
- }
- }
- },
- "node_modules/vitest": {
- "version": "0.30.1",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.30.1.tgz",
- "integrity": "sha512-y35WTrSTlTxfMLttgQk4rHcaDkbHQwDP++SNwPb+7H8yb13Q3cu2EixrtHzF27iZ8v0XCciSsLg00RkPAzB/aA==",
- "dev": true,
- "dependencies": {
- "@types/chai": "^4.3.4",
- "@types/chai-subset": "^1.3.3",
- "@types/node": "*",
- "@vitest/expect": "0.30.1",
- "@vitest/runner": "0.30.1",
- "@vitest/snapshot": "0.30.1",
- "@vitest/spy": "0.30.1",
- "@vitest/utils": "0.30.1",
- "acorn": "^8.8.2",
- "acorn-walk": "^8.2.0",
- "cac": "^6.7.14",
- "chai": "^4.3.7",
- "concordance": "^5.0.4",
- "debug": "^4.3.4",
- "local-pkg": "^0.4.3",
- "magic-string": "^0.30.0",
- "pathe": "^1.1.0",
- "picocolors": "^1.0.0",
- "source-map": "^0.6.1",
- "std-env": "^3.3.2",
- "strip-literal": "^1.0.1",
- "tinybench": "^2.4.0",
- "tinypool": "^0.4.0",
- "vite": "^3.0.0 || ^4.0.0",
- "vite-node": "0.30.1",
- "why-is-node-running": "^2.2.2"
- },
- "bin": {
- "vitest": "vitest.mjs"
- },
- "engines": {
- "node": ">=v14.18.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/antfu"
- },
- "peerDependencies": {
- "@edge-runtime/vm": "*",
- "@vitest/browser": "*",
- "@vitest/ui": "*",
- "happy-dom": "*",
- "jsdom": "*",
- "playwright": "*",
- "safaridriver": "*",
- "webdriverio": "*"
- },
- "peerDependenciesMeta": {
- "@edge-runtime/vm": {
- "optional": true
- },
- "@vitest/browser": {
- "optional": true
- },
- "@vitest/ui": {
- "optional": true
- },
- "happy-dom": {
- "optional": true
- },
- "jsdom": {
- "optional": true
- },
- "playwright": {
- "optional": true
- },
- "safaridriver": {
- "optional": true
- },
- "webdriverio": {
- "optional": true
- }
- }
- },
- "node_modules/vitest/node_modules/@esbuild/android-arm": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
- "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vitest/node_modules/@esbuild/android-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
- "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vitest/node_modules/@esbuild/android-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
- "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vitest/node_modules/@esbuild/darwin-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
- "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vitest/node_modules/@esbuild/darwin-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
- "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vitest/node_modules/@esbuild/freebsd-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
- "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vitest/node_modules/@esbuild/freebsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
- "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vitest/node_modules/@esbuild/linux-arm": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
- "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vitest/node_modules/@esbuild/linux-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
- "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vitest/node_modules/@esbuild/linux-ia32": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
- "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vitest/node_modules/@esbuild/linux-loong64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
- "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vitest/node_modules/@esbuild/linux-mips64el": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
- "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vitest/node_modules/@esbuild/linux-ppc64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
- "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vitest/node_modules/@esbuild/linux-riscv64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
- "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vitest/node_modules/@esbuild/linux-s390x": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
- "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vitest/node_modules/@esbuild/linux-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
- "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vitest/node_modules/@esbuild/netbsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
- "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "netbsd"
- ],
"engines": {
- "node": ">=12"
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "@edge-runtime/vm": "*",
+ "@types/node": "^18.0.0 || >=20.0.0",
+ "@vitest/browser": "1.5.3",
+ "@vitest/ui": "1.5.3",
+ "happy-dom": "*",
+ "jsdom": "*"
+ },
+ "peerDependenciesMeta": {
+ "@edge-runtime/vm": {
+ "optional": true
+ },
+ "@types/node": {
+ "optional": true
+ },
+ "@vitest/browser": {
+ "optional": true
+ },
+ "@vitest/ui": {
+ "optional": true
+ },
+ "happy-dom": {
+ "optional": true
+ },
+ "jsdom": {
+ "optional": true
+ }
}
},
- "node_modules/vitest/node_modules/@esbuild/openbsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
- "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
- "cpu": [
- "x64"
- ],
+ "node_modules/vitest/node_modules/execa": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
+ "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
"dev": true,
- "optional": true,
- "os": [
- "openbsd"
- ],
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^8.0.1",
+ "human-signals": "^5.0.0",
+ "is-stream": "^3.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^5.1.0",
+ "onetime": "^6.0.0",
+ "signal-exit": "^4.1.0",
+ "strip-final-newline": "^3.0.0"
+ },
"engines": {
- "node": ">=12"
+ "node": ">=16.17"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
- "node_modules/vitest/node_modules/@esbuild/sunos-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
- "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
- "cpu": [
- "x64"
- ],
+ "node_modules/vitest/node_modules/get-stream": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
+ "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
"dev": true,
- "optional": true,
- "os": [
- "sunos"
- ],
"engines": {
- "node": ">=12"
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/vitest/node_modules/@esbuild/win32-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
- "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/vitest/node_modules/human-signals": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
+ "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
"dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
"engines": {
- "node": ">=12"
+ "node": ">=16.17.0"
}
},
- "node_modules/vitest/node_modules/@esbuild/win32-ia32": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
- "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
- "cpu": [
- "ia32"
- ],
+ "node_modules/vitest/node_modules/is-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
+ "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
"dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
"engines": {
- "node": ">=12"
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/vitest/node_modules/@esbuild/win32-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
- "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
- "cpu": [
- "x64"
- ],
+ "node_modules/vitest/node_modules/mimic-fn": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
+ "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
"dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
"engines": {
"node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/vitest/node_modules/esbuild": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
- "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
+ "node_modules/vitest/node_modules/npm-run-path": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
+ "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
"dev": true,
- "hasInstallScript": true,
- "bin": {
- "esbuild": "bin/esbuild"
+ "dependencies": {
+ "path-key": "^4.0.0"
},
"engines": {
- "node": ">=12"
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
- "optionalDependencies": {
- "@esbuild/android-arm": "0.18.20",
- "@esbuild/android-arm64": "0.18.20",
- "@esbuild/android-x64": "0.18.20",
- "@esbuild/darwin-arm64": "0.18.20",
- "@esbuild/darwin-x64": "0.18.20",
- "@esbuild/freebsd-arm64": "0.18.20",
- "@esbuild/freebsd-x64": "0.18.20",
- "@esbuild/linux-arm": "0.18.20",
- "@esbuild/linux-arm64": "0.18.20",
- "@esbuild/linux-ia32": "0.18.20",
- "@esbuild/linux-loong64": "0.18.20",
- "@esbuild/linux-mips64el": "0.18.20",
- "@esbuild/linux-ppc64": "0.18.20",
- "@esbuild/linux-riscv64": "0.18.20",
- "@esbuild/linux-s390x": "0.18.20",
- "@esbuild/linux-x64": "0.18.20",
- "@esbuild/netbsd-x64": "0.18.20",
- "@esbuild/openbsd-x64": "0.18.20",
- "@esbuild/sunos-x64": "0.18.20",
- "@esbuild/win32-arm64": "0.18.20",
- "@esbuild/win32-ia32": "0.18.20",
- "@esbuild/win32-x64": "0.18.20"
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/vitest/node_modules/rollup": {
- "version": "3.29.4",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
- "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
+ "node_modules/vitest/node_modules/onetime": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
+ "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
"dev": true,
- "bin": {
- "rollup": "dist/bin/rollup"
+ "dependencies": {
+ "mimic-fn": "^4.0.0"
},
"engines": {
- "node": ">=14.18.0",
- "npm": ">=8.0.0"
+ "node": ">=12"
},
- "optionalDependencies": {
- "fsevents": "~2.3.2"
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/vitest/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==",
+ "node_modules/vitest/node_modules/path-key": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+ "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
"dev": true,
"engines": {
- "node": ">=0.10.0"
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/vitest/node_modules/vite": {
- "version": "4.5.2",
- "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz",
- "integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==",
+ "node_modules/vitest/node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
"dev": true,
- "dependencies": {
- "esbuild": "^0.18.10",
- "postcss": "^8.4.27",
- "rollup": "^3.27.1"
- },
- "bin": {
- "vite": "bin/vite.js"
- },
"engines": {
- "node": "^14.18.0 || >=16.0.0"
+ "node": ">=14"
},
"funding": {
- "url": "https://github.com/vitejs/vite?sponsor=1"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- },
- "peerDependencies": {
- "@types/node": ">= 14",
- "less": "*",
- "lightningcss": "^1.21.0",
- "sass": "*",
- "stylus": "*",
- "sugarss": "*",
- "terser": "^5.4.0"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- },
- "less": {
- "optional": true
- },
- "lightningcss": {
- "optional": true
- },
- "sass": {
- "optional": true
- },
- "stylus": {
- "optional": true
- },
- "sugarss": {
- "optional": true
- },
- "terser": {
- "optional": true
- }
+ "url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/vscode-css-languageservice": {
@@ -27629,15 +26685,6 @@
"node": ">=0.8.0"
}
},
- "node_modules/well-known-symbols": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz",
- "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/whatwg-encoding": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
@@ -28075,6 +27122,7 @@
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
"dev": true,
+ "peer": true,
"engines": {
"node": ">=10"
}
@@ -28098,6 +27146,7 @@
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
"dev": true,
+ "peer": true,
"dependencies": {
"cliui": "^7.0.2",
"escalade": "^3.1.1",
@@ -28124,6 +27173,7 @@
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
"dev": true,
+ "peer": true,
"engines": {
"node": ">=10"
}
diff --git a/training-front-end/package.json b/training-front-end/package.json
index cd4e6a15..441260a7 100644
--- a/training-front-end/package.json
+++ b/training-front-end/package.json
@@ -5,7 +5,7 @@
"scripts": {
"dev": "astro dev",
"start": "astro dev",
- "build": "./bin/build.sh",
+ "build": "./bin/build.sh",
"preview": "astro preview",
"astro": "astro",
"test:unit": "vitest --environment jsdom --root .",
@@ -40,7 +40,7 @@
"@uswds/compile": "^1.1.0",
"@uswds/uswds": "^3.8.0",
"@vitejs/plugin-vue": "^4.1.0",
- "@vitest/coverage-c8": "^0.30.1",
+ "@vitest/coverage-v8": "^1.5.3",
"@vue/cli-plugin-eslint": "^5.0.8",
"@vue/test-utils": "^2.3.2",
"eslint": "^8.38.0",
@@ -51,7 +51,7 @@
"jsdom": "^21.1.1",
"pa11y-ci": "^3.0.1",
"start-server-and-test": "^2.0.3",
- "vitest": "^0.30.1"
+ "vitest": "^1.5.3"
},
"overrides": {
"glob-parent": "^5.1.2"
diff --git a/training-front-end/src/components/__tests__/GspcQuestion.spec.js b/training-front-end/src/components/__tests__/GspcQuestion.spec.js
index 8c51ffed..e414cd53 100644
--- a/training-front-end/src/components/__tests__/GspcQuestion.spec.js
+++ b/training-front-end/src/components/__tests__/GspcQuestion.spec.js
@@ -1,6 +1,6 @@
import { describe, it, expect} from 'vitest'
import { shallowMount } from '@vue/test-utils'
-import GspcQuestion from '@/components/GspcQuestion.vue'
+import GspcQuestion from '../GspcQuestion.vue'
describe('GspcQuestion', () => {
// Sample question data for testing
@@ -15,7 +15,7 @@ describe('GspcQuestion', () => {
}
// Sample user answer for testing
- const userAnswer = 0 // Assuming the user selected the first choice
+ const userAnswer = 0
it('renders question text correctly', () => {
const wrapper = shallowMount(GspcQuestion, {
@@ -41,14 +41,22 @@ describe('GspcQuestion', () => {
props: { question, selection: null }
})
await wrapper.find('input[value="0"]').setChecked()
- expect(wrapper.emitted('select_answer')[0]).toEqual([0])
- })
-
- it('correctly highlights selected choice', async () => {
- const wrapper = shallowMount(GspcQuestion, {
- props: { question, selection: userAnswer }
+ const emittedEvent = wrapper.emitted('select_answer')[0][0]
+ expect(emittedEvent).toEqual({
+ correct: true,
+ question: question.text,
+ question_id: question.id,
+ response: question.choices[0].text,
+ response_id: question.choices[0].id
})
- const selectedChoice = wrapper.find(`input[value="${userAnswer}"]`)
- expect(selectedChoice.element.checked).toBe(true)
})
+
+ // it('correctly highlights selected choice', async () => {
+ // const wrapper = shallowMount(GspcQuestion, {
+ // props: { question, selection: userAnswer }
+ // })
+ // const selectedChoice = wrapper.find(`input[value="${userAnswer}"]`)
+
+ // expect(selectedChoice.element.checked).toBe(true)
+ // })
})
\ No newline at end of file
diff --git a/training-front-end/src/components/__tests__/GspcRegistration.spec.js b/training-front-end/src/components/__tests__/GspcRegistration.spec.js
index 6c2aece3..270feec1 100644
--- a/training-front-end/src/components/__tests__/GspcRegistration.spec.js
+++ b/training-front-end/src/components/__tests__/GspcRegistration.spec.js
@@ -19,8 +19,8 @@ describe('GspcRegistration', () => {
})
const wrapper = await mount(GspcRegistration)
await flushPromises()
- expect(wrapper.text()).toContain("GSPC Registration")
- expect(wrapper.text()).toContain("Enter your email address to login. You'll receive an email with an access link.")
+ expect(wrapper.text()).toContain("Verify GSPC coursework and experience")
+ expect(wrapper.text()).toContain("Enter your email address")
})
it('shows start registration form once user is known', async () => {
@@ -30,6 +30,6 @@ describe('GspcRegistration', () => {
profile.set({name:"John Smith", jwt:"some-token-value"})
const wrapper = await mount(GspcRegistration)
await flushPromises()
- expect(wrapper.text()).toContain("GSPC Placeholder")
+ expect(wrapper.text()).toContain("GSA SmartPay® Program Certification (GSPC) Requirements")
})
})
\ No newline at end of file
From 033136f213026803bbbb8f888c23174e4ae2f32d Mon Sep 17 00:00:00 2001
From: John Labbate
Date: Tue, 30 Apr 2024 11:18:26 -0400
Subject: [PATCH 12/24] lint error fix.
---
training-front-end/package.json | 2 +-
.../src/components/__tests__/GspcQuestion.spec.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/training-front-end/package.json b/training-front-end/package.json
index 441260a7..64fbc953 100644
--- a/training-front-end/package.json
+++ b/training-front-end/package.json
@@ -10,7 +10,7 @@
"astro": "astro",
"test:unit": "vitest --environment jsdom --root .",
"test:coverage": "vitest --coverage",
- "lint": "eslint 'src' --ext .vue,.js,.astro",
+ "lint": "eslint src --ext .vue,.js,.astro",
"serve": "npm run build && npm run preview -- --port 8080",
"pa11y-ci": "npm run pa11y-ci:desktop && npm run pa11y-ci:mobile",
"pa11y-ci:desktop": "pa11y-ci --config ./.pa11yci-desktop --sitemap http://localhost:8080/sitemap-0.xml --sitemap-find \"^https://training.smartpay.gsa.gov/\" --sitemap-replace \"http://localhost:8080/\"",
diff --git a/training-front-end/src/components/__tests__/GspcQuestion.spec.js b/training-front-end/src/components/__tests__/GspcQuestion.spec.js
index e414cd53..efa44e44 100644
--- a/training-front-end/src/components/__tests__/GspcQuestion.spec.js
+++ b/training-front-end/src/components/__tests__/GspcQuestion.spec.js
@@ -15,7 +15,7 @@ describe('GspcQuestion', () => {
}
// Sample user answer for testing
- const userAnswer = 0
+ //const userAnswer = 0
it('renders question text correctly', () => {
const wrapper = shallowMount(GspcQuestion, {
From 2988a32c391168cd68b222051829f88b3e028305 Mon Sep 17 00:00:00 2001
From: John Labbate
Date: Wed, 1 May 2024 15:29:48 -0400
Subject: [PATCH 13/24] Add testing to frontend.
---
training-front-end/.vscode/settings.json | 5 +
.../src/components/GspcQuestions.vue | 43 ++----
.../src/components/GspcRegistration.vue | 38 ++++-
.../components/__tests__/GspcQuestion.spec.js | 36 +++--
.../__tests__/GspcQuestions.spec.js | 141 ++++++++++++++++++
.../__tests__/GspcRegistration.spec.js | 85 ++++++++++-
.../src/pages/gspc_registration/index.astro | 2 +-
7 files changed, 303 insertions(+), 47 deletions(-)
create mode 100644 training-front-end/.vscode/settings.json
create mode 100644 training-front-end/src/components/__tests__/GspcQuestions.spec.js
diff --git a/training-front-end/.vscode/settings.json b/training-front-end/.vscode/settings.json
new file mode 100644
index 00000000..d2d15697
--- /dev/null
+++ b/training-front-end/.vscode/settings.json
@@ -0,0 +1,5 @@
+{
+ "cSpell.words": [
+ "Gspc"
+ ]
+}
\ No newline at end of file
diff --git a/training-front-end/src/components/GspcQuestions.vue b/training-front-end/src/components/GspcQuestions.vue
index 8bc87eed..88699740 100644
--- a/training-front-end/src/components/GspcQuestions.vue
+++ b/training-front-end/src/components/GspcQuestions.vue
@@ -8,51 +8,36 @@
import SpinnerGraphic from './SpinnerGraphic.vue'
const emit = defineEmits(['submitGspcRegistration'])
-
- const questions =
- [{"id": 0,
- "text": "I have met the coursework requirement during the GSA SmartPay Training Forum by attending at least two GSA Qualifying classes and at least five Bank/Brand Qualifying classes, as outlined in Smart Bulletin No. 022.",
- "type": "MultipleChoiceSingleSelect",
- "choices": [{"id": 0, "text": "Yes", "correct": true}, {"id": 1, "text": "No", "correct": false}]},
- {"id": 1,
- "text": "I have met the experience requirement by having a minimum of six months of continuous, hands-on experience working in an agency/organization's GSA SmartPay Program prior to receiving the GSPC.",
- "type": "MultipleChoiceSingleSelect",
- "choices": [{"id": 0, "text": "Yes", "correct": true}, {"id": 1, "text": "No", "correct": false}]},
- ]
-
- //GSPC
- //Id UserId JSON(List QuestionId QuestionSting AnswerId AnswerString Correct(bool)) CreatedOn
+
+ const props = defineProps({
+ 'questions': {
+ type: Object,
+ required: true
+ },
+ })
const question_index = ref(0)
const user_answers = reactive([])
const has_submitted = ref(false)
let show_intro = ref(true)
- const number_of_questions = computed(() => questions.length)
- const current_question = computed(() => questions[question_index.value])
+ const number_of_questions = computed(() => props.questions.length)
+ const current_question = computed(() => props.questions[question_index.value])
const is_current_unanswered = computed(() => user_answers[question_index.value] === undefined )
- const last_question = computed(() => question_index.value == (questions.length -1))
+ const last_question = computed(() => question_index.value == (props.questions.length -1))
const can_submit = computed(() => !is_current_unanswered.value && !has_submitted.value)
function start() {
show_intro.value = false
}
- function windowStateListener(event) {
- if (event.state) {
- question_index.value = event.state.page
- }
- }
-
onMounted(async () => {
window.addEventListener("beforeunload", exit_warning)
const state = { page: 0 };
history.replaceState(state, "", "");
- window.addEventListener("popstate", windowStateListener)
})
onBeforeUnmount(() => {
- window.removeEventListener('popstate', windowStateListener)
window.removeEventListener('beforeunload', exit_warning)
})
@@ -64,9 +49,6 @@
}
function previous_question(){
- if (question_index.value <= 0) {
- return
- }
question_index.value -= 1
const state = { page: question_index.value }
const url = ""
@@ -101,6 +83,7 @@
You can complete the verification steps to receive your GSA SmartPay® Program Certification if you meet these requirements.
@@ -123,6 +106,7 @@
{
const urlParams = new URLSearchParams(window.location.search);
expirationDate = urlParams.get('expirationDate')
@@ -135,7 +165,7 @@
diff --git a/training-front-end/src/components/__tests__/GspcQuestion.spec.js b/training-front-end/src/components/__tests__/GspcQuestion.spec.js
index efa44e44..2ae8d6ef 100644
--- a/training-front-end/src/components/__tests__/GspcQuestion.spec.js
+++ b/training-front-end/src/components/__tests__/GspcQuestion.spec.js
@@ -15,7 +15,7 @@ describe('GspcQuestion', () => {
}
// Sample user answer for testing
- //const userAnswer = 0
+ const userAnswer = 0
it('renders question text correctly', () => {
const wrapper = shallowMount(GspcQuestion, {
@@ -51,12 +51,30 @@ describe('GspcQuestion', () => {
})
})
- // it('correctly highlights selected choice', async () => {
- // const wrapper = shallowMount(GspcQuestion, {
- // props: { question, selection: userAnswer }
- // })
- // const selectedChoice = wrapper.find(`input[value="${userAnswer}"]`)
-
- // expect(selectedChoice.element.checked).toBe(true)
- // })
+ it('emits select_answer event with incorrect choice', async () => {
+ const wrapper = shallowMount(GspcQuestion, {
+ props: { question, selection: null }
+ })
+
+ // Assuming the user selects the incorrect choice (index 1)
+ await wrapper.find('input[value="1"]').setChecked()
+
+ // Verify that the emitted event contains the expected data for an incorrect choice
+ const emittedEvent = wrapper.emitted('select_answer')[0][0]
+ expect(emittedEvent).toEqual({
+ correct: false, // Expecting the choice to be incorrect
+ question: question.text,
+ question_id: question.id,
+ response: question.choices[1].text, // Expecting the text of the incorrect choice
+ response_id: question.choices[1].id // Expecting the id of the incorrect choice
+ })
+ })
+
+ it('correctly highlights selected choice', async () => {
+ const wrapper = shallowMount(GspcQuestion, {
+ props: { question, selection: {response_id: userAnswer} }
+ })
+ const selectedChoice = wrapper.find(`input[value="${userAnswer}"]`)
+ expect(selectedChoice.element.checked).toBe(true)
+ })
})
\ No newline at end of file
diff --git a/training-front-end/src/components/__tests__/GspcQuestions.spec.js b/training-front-end/src/components/__tests__/GspcQuestions.spec.js
new file mode 100644
index 00000000..80d64f23
--- /dev/null
+++ b/training-front-end/src/components/__tests__/GspcQuestions.spec.js
@@ -0,0 +1,141 @@
+import { describe, it, expect, vi} from 'vitest'
+import { shallowMount, mount } from '@vue/test-utils'
+import GspcQuestions from '../GspcQuestions.vue'
+
+async function startForm(wrapper) {
+ await wrapper.find('#start-button').trigger('click')
+}
+
+async function selectAnswer(wrapper, index) {
+ await wrapper.find(`input[value="${index}"]`).setChecked()
+}
+
+describe('GspcQuestions', () => {
+ const questions = [
+ {"id": 0,
+ "text": "Question 1",
+ "type": "MultipleChoiceSingleSelect",
+ "choices": [{"id": 0, "text": "Yes", "correct": true}, {"id": 1, "text": "No", "correct": false}]},
+ {"id": 1,
+ "text": "Question 2",
+ "type": "MultipleChoiceSingleSelect",
+ "choices": [{"id": 0, "text": "Yes", "correct": true}, {"id": 1, "text": "No", "correct": false}]},
+ ]
+
+ it('shows intro section initially and hides it on "Continue" button click', async () => {
+ const wrapper = shallowMount(GspcQuestions, {
+ props: { questions }
+ })
+
+ expect(wrapper.find('.usa-prose').exists()).toBe(true)
+ expect(wrapper.find('#start-button').exists()).toBe(true)
+
+ await wrapper.find('#start-button').trigger('click')
+
+ expect(wrapper.find('#start-button').exists()).toBe(false)
+ })
+
+ it('Nest button should be disabled when no answer has been selected', async () => {
+ const wrapper = await shallowMount(GspcQuestions, {
+ props: { questions }
+ })
+
+ await startForm(wrapper)
+
+ const button = wrapper.find('#next-button')
+ expect(button.element.disabled).toBe(true)
+ })
+
+ it('Nest button should not be disabled when an answer has been selected', async () => {
+ const wrapper = mount(GspcQuestions, {
+ props: { questions }
+ })
+
+ await startForm(wrapper)
+ await selectAnswer(wrapper, 0)
+
+ const button = wrapper.find('#next-button')
+ expect(button.element.disabled).toBe(false)
+ })
+
+ it('Previous button does not show on first question', async () => {
+ const wrapper = shallowMount(GspcQuestions, {
+ props: { questions }
+ })
+
+ await startForm(wrapper)
+
+ // Assert that the previous button does not exist
+ const previousButton = wrapper.find('#previous-button');
+ expect(previousButton.exists()).toBe(false);
+ })
+
+ it('navigates to the next question and back', async () => {
+ const wrapper = mount(GspcQuestions, {
+ props: { questions }
+ })
+
+ await startForm(wrapper)
+ await selectAnswer(wrapper, 0)
+
+ await wrapper.find('#next-button').trigger('click')
+
+ expect(wrapper.text()).toContain("Question 2")
+
+ await wrapper.find('#previous-button').trigger('click') // Move to previous question
+
+ expect(wrapper.text()).toContain("Question 1")
+ })
+
+ it('submits the quiz', async () => {
+ const wrapper = mount(GspcQuestions, {
+ props: { questions }
+ })
+
+ await startForm(wrapper)
+
+ await selectAnswer(wrapper, 0)
+ await wrapper.find('#next-button').trigger('click')
+
+ await selectAnswer(wrapper, 0)
+ await wrapper.find('.usa-button').trigger('click') // Submit quiz
+
+ expect(wrapper.emitted('submitGspcRegistration')).toBeTruthy()
+ expect(wrapper.vm.has_submitted).toBe(true)
+ })
+
+ it('shows "Submit" button when on the last question', async () => {
+ const wrapper = mount(GspcQuestions, {
+ props: { questions }
+ })
+
+ await startForm(wrapper)
+
+ await selectAnswer(wrapper, 0)
+ await wrapper.find('#next-button').trigger('click')
+
+ const submitButton = wrapper.find('#submit-button');
+ expect(submitButton.exists()).toBe(true);
+ })
+
+ it('should add window listeners on mount', async () => {
+ const addEventListenerMock = vi.spyOn(global, 'addEventListener').mockImplementation(() => {})
+ await mount(GspcQuestions, {
+ props: { questions }
+ })
+
+ expect(addEventListenerMock).toBeCalled(1)
+ expect(addEventListenerMock).toHaveBeenNthCalledWith(1, 'beforeunload', expect.any(Function))
+ })
+
+ it('should remove window listeners on mount', async () => {
+ const wrapper = mount(GspcQuestions, {
+ props: { questions }
+ })
+ const removeEventListenerMock = vi.spyOn(global, 'removeEventListener').mockImplementation(() => {})
+
+ wrapper.unmount()
+ expect(removeEventListenerMock).toBeCalled(1)
+ expect(removeEventListenerMock).toHaveBeenNthCalledWith(1, 'beforeunload', expect.any(Function))
+ })
+})
\ No newline at end of file
diff --git a/training-front-end/src/components/__tests__/GspcRegistration.spec.js b/training-front-end/src/components/__tests__/GspcRegistration.spec.js
index 270feec1..1c0acb5e 100644
--- a/training-front-end/src/components/__tests__/GspcRegistration.spec.js
+++ b/training-front-end/src/components/__tests__/GspcRegistration.spec.js
@@ -6,6 +6,13 @@ import GspcRegistration from '../GspcRegistration.vue'
import { cleanStores } from 'nanostores'
import { profile } from '../../stores/user.js'
+async function setUserCredentials(){
+ vi.spyOn(global, 'fetch').mockImplementation(() => {
+ return Promise.resolve({ok: false, status:404, json: () => Promise.resolve([]) })
+ })
+ profile.set({name:"John Smith", jwt:"some-token-value"})
+}
+
describe('GspcRegistration', () => {
afterEach(() => {
vi.restoreAllMocks()
@@ -24,12 +31,82 @@ describe('GspcRegistration', () => {
})
it('shows start registration form once user is known', async () => {
- vi.spyOn(global, 'fetch').mockImplementation(() => {
- return Promise.resolve({ok: false, status:404, json: () => Promise.resolve([]) })
- })
- profile.set({name:"John Smith", jwt:"some-token-value"})
+ setUserCredentials()
const wrapper = await mount(GspcRegistration)
await flushPromises()
expect(wrapper.text()).toContain("GSA SmartPay® Program Certification (GSPC) Requirements")
})
+
+ it('renders USWDSAlert when error is present', async () => {
+ // Mock the error
+ const error = { name: 'Mock Error', message: 'This is a mock error message' };
+
+ // Mount the component with error prop
+ const wrapper = mount(GspcRegistration, {
+ props: {
+ error: error
+ }
+ });
+
+ // Find the USWDSAlert component
+ const uswdsAlert = wrapper.findComponent({ name: 'USWDSAlert' });
+ expect(uswdsAlert.exists()).toBe(true);
+
+ // Assert the props passed to USWDSAlert
+ expect(uswdsAlert.props('status')).toBe('error');
+ expect(uswdsAlert.props('heading')).toBe(error.name);
+ expect(wrapper.text()).toContain(error.message)
+ });
+
+
+ it('should submit registration successfully', async () => {
+ setUserCredentials()
+ const wrapper = mount(GspcRegistration, {});
+
+ const mockedResponse = { passed: true };
+ global.fetch = vi.fn().mockResolvedValueOnce({
+ ok: true,
+ json: () => Promise.resolve(mockedResponse)
+ });
+
+ await wrapper.vm.submitGspcRegistration([]);
+
+ expect(wrapper.vm.certPassed).toBe(true);
+ expect(wrapper.vm.certFailed).toBe(false);
+ expect(wrapper.vm.error).toBe(null);
+ expect(wrapper.text()).toContain("Congratulations")
+ });
+
+ it('should submit failed registration successfully', async () => {
+ setUserCredentials()
+ const wrapper = mount(GspcRegistration, {});
+
+ const mockedResponse = { passed: false };
+ global.fetch = vi.fn().mockResolvedValueOnce({
+ ok: true,
+ json: () => Promise.resolve(mockedResponse)
+ });
+
+ await wrapper.vm.submitGspcRegistration([]);
+
+ expect(wrapper.vm.certPassed).toBe(false);
+ expect(wrapper.vm.certFailed).toBe(true);
+ expect(wrapper.vm.error).toBe(null);
+ expect(wrapper.text()).toContain("You Don't Meet the Requirements")
+ });
+
+ it('should handle server error', async () => {
+ setUserCredentials()
+ const wrapper = mount(GspcRegistration, {});
+
+ const errorMessage = 'There was a problem connecting with the server';
+ global.fetch = vi.fn().mockRejectedValueOnce(new Error(errorMessage));
+
+ await wrapper.vm.submitGspcRegistration([]);
+
+ expect(wrapper.vm.certPassed).toBe(false);
+ expect(wrapper.vm.certFailed).toBe(false);
+ expect(wrapper.vm.error.message).toBe(errorMessage);
+ expect(wrapper.text()).toContain(errorMessage)
+ });
})
\ No newline at end of file
diff --git a/training-front-end/src/pages/gspc_registration/index.astro b/training-front-end/src/pages/gspc_registration/index.astro
index b65d0a47..357cab3d 100644
--- a/training-front-end/src/pages/gspc_registration/index.astro
+++ b/training-front-end/src/pages/gspc_registration/index.astro
@@ -8,7 +8,7 @@ const pageTitle = "GSPC Registration";
- GSPC Registration
+ GSA SmartPay® Program Certification (GSPC)
Date: Thu, 2 May 2024 10:01:46 -0400
Subject: [PATCH 14/24] minor fixes to title and background.
---
.../src/components/GspcQuestions.vue | 8 +++++--
.../src/components/GspcRegistration.vue | 21 ++++++++++++-------
.../src/pages/gspc_registration/index.astro | 5 ++++-
3 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/training-front-end/src/components/GspcQuestions.vue b/training-front-end/src/components/GspcQuestions.vue
index 88699740..fc2d637b 100644
--- a/training-front-end/src/components/GspcQuestions.vue
+++ b/training-front-end/src/components/GspcQuestions.vue
@@ -7,7 +7,8 @@
import NavigateBack from "./icons/NavigateBack.vue"
import SpinnerGraphic from './SpinnerGraphic.vue'
- const emit = defineEmits(['submitGspcRegistration'])
+ const emit = defineEmits(['submitGspcRegistration', 'startQuiz'])
+
const props = defineProps({
'questions': {
@@ -29,6 +30,7 @@
function start() {
show_intro.value = false
+ emit('startQuiz')
}
onMounted(async () => {
@@ -90,7 +92,9 @@
Continue to verify coursework and experience
-
+
-
Before verifying your GSPC coursework and experience, you'll need to create and complete your profile.
-
Congratulations You Earned Your GSA SmartPay® Program Certificate (GSPC)
-
You have met the requirements to earn a GSA SmartPay® Program Certificate (GSPC). Your certificate has been emailed to you. Or, you may download your certificate below.
+
Congratulations You Earned Your GSA SmartPay Program Certificate (GSPC)
+
You have met the requirements to earn a GSA SmartPay Program Certificate (GSPC). Your certificate has been emailed to you. Or, you may download your certificate below.
Return to the GSA SmartPay Training Home Page
-
You Don't Meet the Requirements for GSA SmartPay® Program Certification (GSPC)
+
You Don't Meet the Requirements for GSA SmartPay Program Certification (GSPC)
Once you have met the coursework and experience requirement of six months of continuous, hands-on experience working with the GSA SmartPay program please return to the link in your email to reapply.
If you have any questions ,please reference Smart Bulletin No. 022 or contact the GSPC Program Manager at smartpaygspc@gsa.com .
Return to the GSA SmartPay Training Home Page
@@ -167,6 +173,7 @@
diff --git a/training-front-end/src/pages/gspc_registration/index.astro b/training-front-end/src/pages/gspc_registration/index.astro
index 357cab3d..a810eb3c 100644
--- a/training-front-end/src/pages/gspc_registration/index.astro
+++ b/training-front-end/src/pages/gspc_registration/index.astro
@@ -3,11 +3,14 @@ import BaseLayout from '@layouts/BaseLayout.astro';
import HeroTraining from '@components/HeroTraining.astro';
import GspcRegistration from '@components/GspcRegistration.vue';
-const pageTitle = "GSPC Registration";
+const pageTitle = "GSA SmartPay® Program Certification";
---
+
+ Card/Account Holders and Approving Officials
+
GSA SmartPay® Program Certification (GSPC)
Date: Thu, 2 May 2024 10:06:06 -0400
Subject: [PATCH 15/24] Lint error fix.
---
training/services/gspc.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/training/services/gspc.py b/training/services/gspc.py
index 5d0047e3..ffe64741 100644
--- a/training/services/gspc.py
+++ b/training/services/gspc.py
@@ -25,4 +25,4 @@ def grade(self, user_id: int, submission: GspcSubmission) -> GspcResult:
passed=passed,
)
- return result
+ return result
\ No newline at end of file
From 965d1ba37dc4bba985fd9349ea300db0aeaec98d Mon Sep 17 00:00:00 2001
From: John Labbate
Date: Thu, 2 May 2024 10:13:01 -0400
Subject: [PATCH 16/24] Lint error fix.
---
training/api/api_v1/gspc.py | 2 +-
training/api/deps.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/training/api/api_v1/gspc.py b/training/api/api_v1/gspc.py
index a6ae43e6..6af2c9e3 100644
--- a/training/api/api_v1/gspc.py
+++ b/training/api/api_v1/gspc.py
@@ -59,4 +59,4 @@ def submit_gspc_registration(
user: dict[str, Any] = Depends(JWTUser())
):
result = gspc_service.grade(user_id=user["id"], submission=submission)
- return result
\ No newline at end of file
+ return result
diff --git a/training/api/deps.py b/training/api/deps.py
index 78732668..4933df7d 100644
--- a/training/api/deps.py
+++ b/training/api/deps.py
@@ -46,4 +46,4 @@ def gspc_invite_repository(db: Session = Depends(db)) -> GspcInviteRepository:
def gspc_service(db: Session = Depends(db)) -> GspcService:
- return GspcService(db)
\ No newline at end of file
+ return GspcService(db)
From 1cda6477f11966700f9cf49f5763e8b9251d3bc9 Mon Sep 17 00:00:00 2001
From: John Labbate
Date: Thu, 2 May 2024 10:14:47 -0400
Subject: [PATCH 17/24] Lint error fix.
---
training/services/gspc.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/training/services/gspc.py b/training/services/gspc.py
index ffe64741..5d0047e3 100644
--- a/training/services/gspc.py
+++ b/training/services/gspc.py
@@ -25,4 +25,4 @@ def grade(self, user_id: int, submission: GspcSubmission) -> GspcResult:
passed=passed,
)
- return result
\ No newline at end of file
+ return result
From 79a3144c11ab8ea35b8fae7f6b140acb471015c3 Mon Sep 17 00:00:00 2001
From: John Labbate
Date: Thu, 9 May 2024 10:33:03 -0400
Subject: [PATCH 18/24] WIP
---
...a5fbdcd0e719_add_gspc_completions_table.py | 35 ++++++++
data/blank_certificates/c_gspc.pdf | Bin 0 -> 221933 bytes
.../src/components/GspcRegistration.vue | 7 ++
training/models/__init__.py | 1 +
training/models/gspc_completion.py | 15 ++++
training/repositories/__init__.py | 1 +
training/repositories/certificate.py | 1 +
training/repositories/gspc_completion.py | 17 ++++
training/schemas/gspc_result.py | 1 +
training/schemas/gspc_submission.py | 10 ++-
training/services/certificate.py | 20 +++++
training/services/gspc.py | 84 ++++++++++++++++--
training/services/quiz.py | 2 +-
13 files changed, 186 insertions(+), 8 deletions(-)
create mode 100644 alembic/versions/a5fbdcd0e719_add_gspc_completions_table.py
create mode 100644 data/blank_certificates/c_gspc.pdf
create mode 100644 training/models/gspc_completion.py
create mode 100644 training/repositories/gspc_completion.py
diff --git a/alembic/versions/a5fbdcd0e719_add_gspc_completions_table.py b/alembic/versions/a5fbdcd0e719_add_gspc_completions_table.py
new file mode 100644
index 00000000..2d768acc
--- /dev/null
+++ b/alembic/versions/a5fbdcd0e719_add_gspc_completions_table.py
@@ -0,0 +1,35 @@
+"""add gspc_completions table
+
+Revision ID: a5fbdcd0e719
+Revises: 51b251b1ec2a
+Create Date: 2024-05-08 10:43:09.569708
+
+"""
+from alembic import op
+import sqlalchemy as sa
+from sqlalchemy.dialects import postgresql
+
+
+# revision identifiers, used by Alembic.
+revision = 'a5fbdcd0e719'
+down_revision = '51b251b1ec2a'
+branch_labels = None
+depends_on = None
+
+
+def upgrade() -> None:
+ op.create_table(
+ 'gspc_completions',
+ sa.Column('id', sa.Integer(), nullable=False),
+ sa.Column('user_id', sa.Integer(), nullable=False),
+ sa.Column('passed', sa.Boolean(), nullable=False),
+ sa.Column('certification_expiration_date', sa.Date, nullable=False),
+ sa.Column('submit_ts', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
+ sa.Column('responses', postgresql.JSONB(astext_type=sa.Text()), nullable=False),
+ sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
+ sa.PrimaryKeyConstraint('id')
+ )
+
+
+def downgrade() -> None:
+ op.drop_table('gspc_completions')
diff --git a/data/blank_certificates/c_gspc.pdf b/data/blank_certificates/c_gspc.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..ff9e8564b2bac3618565455ecac555275f240bfa
GIT binary patch
literal 221933
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