Compare commits

..

17 Commits

Author SHA1 Message Date
Renovate Bot
cb60fe446c Update dependency tailwindcss to v4
Some checks failed
Check usage of free licenses / build-static-assets (pull_request) Successful in 1m40s
Playwright Tests / test (pull_request) Failing after 1m42s
Add copyright notice / copyright_notice (pull_request) Successful in 2m11s
Build Nginx-based docker image / build-static-assets (push) Failing after 12m53s
2025-06-15 02:04:19 +00:00
8306cfe249 Merge pull request 'Adjust group creation to avoid a full reload' (#283) from group-specs into main
All checks were successful
Check usage of free licenses / build-static-assets (push) Successful in 44s
Playwright Tests / test (push) Successful in 4m18s
Build Nginx-based docker image / build-static-assets (push) Successful in 5m1s
Reviewed-on: #283
2025-06-14 17:05:46 +00:00
67e4ad5d16 Refactor feature to add groups avoiding reload and improve specs
All checks were successful
Build Nginx-based docker image / build-static-assets (push) Successful in 2m0s
Check usage of free licenses / build-static-assets (pull_request) Successful in 45s
Add copyright notice / copyright_notice (pull_request) Successful in 59s
Playwright Tests / test (pull_request) Successful in 3m44s
2025-06-14 11:27:44 +02:00
5164491e64 Merge pull request 'Extract API mocks to their own file' (#282) from extract-mocks into main
All checks were successful
Check usage of free licenses / build-static-assets (push) Successful in 34s
Playwright Tests / test (push) Successful in 4m7s
Build Nginx-based docker image / build-static-assets (push) Successful in 4m44s
Reviewed-on: #282
2025-06-14 07:49:10 +00:00
89e9c211d7 Refactor: extract groups specs to their own file 2025-06-14 09:46:35 +02:00
02760e5068 Extract API mocks to their own file
All checks were successful
Check usage of free licenses / build-static-assets (pull_request) Successful in 1m11s
Add copyright notice / copyright_notice (pull_request) Successful in 1m27s
Build Nginx-based docker image / build-static-assets (push) Successful in 4m12s
Playwright Tests / test (pull_request) Successful in 4m18s
2025-06-14 09:44:31 +02:00
2ebd9796e3 Merge pull request 'Fix minor UI bugs and test guest CRUD' (#281) from improve-specs-guests into main
All checks were successful
Check usage of free licenses / build-static-assets (push) Successful in 46s
Playwright Tests / test (push) Successful in 4m14s
Build Nginx-based docker image / build-static-assets (push) Successful in 4m46s
Reviewed-on: #281
2025-06-14 06:35:14 +00:00
c50263f760 Fix bug where updated guest is duplicated
All checks were successful
Build Nginx-based docker image / build-static-assets (push) Successful in 2m20s
Check usage of free licenses / build-static-assets (pull_request) Successful in 42s
Add copyright notice / copyright_notice (pull_request) Successful in 55s
Playwright Tests / test (pull_request) Successful in 3m3s
2025-06-14 08:22:13 +02:00
5c524c2559 Merge create and list guests into a single test 2025-06-14 07:28:03 +02:00
ae5a986f25 Merge pull request 'Update dependency bcrypt to v6' (#251) from renovate/bcrypt-6.x into main
All checks were successful
Check usage of free licenses / build-static-assets (push) Successful in 53s
Playwright Tests / test (push) Successful in 4m13s
Build Nginx-based docker image / build-static-assets (push) Successful in 5m21s
Reviewed-on: #251
2025-06-14 05:18:57 +00:00
0a28127c4d Merge pull request 'Update dependency @types/node to v22.15.31' (#276) from renovate/node-22.x into main
Some checks failed
Build Nginx-based docker image / build-static-assets (push) Has been cancelled
Check usage of free licenses / build-static-assets (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
Reviewed-on: #276
2025-06-14 05:18:51 +00:00
7ae23204ff Merge pull request 'Update dependency zod to v3.25.64' (#266) from renovate/zod-3.x-lockfile into main
Some checks failed
Build Nginx-based docker image / build-static-assets (push) Has been cancelled
Check usage of free licenses / build-static-assets (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
Reviewed-on: #266
2025-06-14 05:18:41 +00:00
c000d1c9b4 Merge pull request 'Update dependency postcss to v8.5.5' (#280) from renovate/postcss-8.x into main
Some checks failed
Build Nginx-based docker image / build-static-assets (push) Has been cancelled
Check usage of free licenses / build-static-assets (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
Reviewed-on: #280
2025-06-14 05:18:26 +00:00
Renovate Bot
3b95dde33e Update dependency bcrypt to v6
All checks were successful
Check usage of free licenses / build-static-assets (pull_request) Successful in 3m29s
Add copyright notice / copyright_notice (pull_request) Successful in 3m53s
Build Nginx-based docker image / build-static-assets (push) Successful in 21m46s
Playwright Tests / test (pull_request) Successful in 19m39s
2025-06-14 02:05:44 +00:00
Renovate Bot
2cae594794 Update dependency zod to v3.25.64
All checks were successful
Add copyright notice / copyright_notice (pull_request) Successful in 9m30s
Check usage of free licenses / build-static-assets (pull_request) Successful in 9m53s
Build Nginx-based docker image / build-static-assets (push) Successful in 29m18s
Playwright Tests / test (pull_request) Successful in 23m16s
2025-06-14 02:05:27 +00:00
Renovate Bot
46fa8133c3 Update dependency postcss to v8.5.5
All checks were successful
Check usage of free licenses / build-static-assets (pull_request) Successful in 1m26s
Add copyright notice / copyright_notice (pull_request) Successful in 2m26s
Playwright Tests / test (pull_request) Successful in 18m57s
Build Nginx-based docker image / build-static-assets (push) Successful in 24m30s
2025-06-14 02:05:11 +00:00
Renovate Bot
5c5766dfe0 Update dependency @types/node to v22.15.31
All checks were successful
Add copyright notice / copyright_notice (pull_request) Successful in 2m11s
Check usage of free licenses / build-static-assets (pull_request) Successful in 58s
Build Nginx-based docker image / build-static-assets (push) Successful in 21m10s
Playwright Tests / test (pull_request) Successful in 24m7s
2025-06-14 02:05:02 +00:00
10 changed files with 317 additions and 622 deletions

View File

@ -18,6 +18,7 @@ import { Toast } from 'primereact/toast';
import { Suspense, useEffect, useRef, useState } from 'react';
import InvitationsBoard from '@/app/ui/invitations/board';
import { Invitation, InvitationSerializer } from '@/app/lib/invitation';
import { Entity } from '@/app/lib/definitions';
export default function Page() {
@ -88,7 +89,22 @@ export default function Page() {
const [invitations, setInvitations] = useState<Array<Invitation>>([]);
function updateList<T extends Entity>(originalList: T[], element: T): T[] {
{
const index = originalList.findIndex(g => g.id === element?.id);
if (index !== -1) {
// Replace existing element
return [
element!,
...originalList.slice(0, index),
...originalList.slice(index + 1)
];
} else {
// Add new element at the start
return [element!, ...originalList];
}
}
}
return (
<div className="w-full">
@ -100,7 +116,7 @@ export default function Page() {
key={guestBeingEdited?.id}
groups={groups}
onCreate={(newGuest) => {
setGuests([newGuest!, ...guests]);
setGuests(guests => updateList(guests, newGuest));
setGuestBeingEdited(undefined);
}}
guest={guestBeingEdited}
@ -128,7 +144,10 @@ export default function Page() {
<GroupFormDialog
key={groupBeingEdited?.id}
groups={groups}
onCreate={() => { refreshGroups(); setGroupBeingEdited(undefined) }}
onCreate={(newGroup) => {
setGroups(groups => updateList(groups, newGroup));
setGroupBeingEdited(undefined)
}}
group={groupBeingEdited}
visible={groupBeingEdited !== undefined}
onHide={() => { setGroupBeingEdited(undefined) }}

View File

@ -41,7 +41,7 @@ export class AbstractApi<T extends Entity> implements Api<T> {
});
}
update(serializable: Serializable<T>, object: T, callback: () => void): void {
update(serializable: Serializable<T>, object: T, callback: (updatedObject: T) => void): void {
const endpoint = object.id ? `/api/${getSlug()}/${serializable.apiPath()}/${object.id}` : `/api/${getSlug()}/${serializable.apiPath()}`;
fetch(endpoint, {
@ -52,7 +52,10 @@ export class AbstractApi<T extends Entity> implements Api<T> {
'Accept': 'application/json',
'X-CSRF-TOKEN': getCsrfToken(),
}
}).then(callback)
}).then((response) => response.json())
.then((data) => {
callback(serializable.fromJson(data));
})
.catch((error) => console.error(error));
}

View File

@ -14,7 +14,7 @@ import { useState } from 'react';
export default function GroupFormDialog({ groups, onCreate, onHide, group, visible }: {
groups: Group[],
onCreate?: () => void,
onCreate?: (newGroup: Group) => void,
onHide: () => void,
group?: Group,
visible: boolean,
@ -46,15 +46,15 @@ export default function GroupFormDialog({ groups, onCreate, onHide, group, visib
group.color = color;
group.parentId = parentId;
api.update(serializer, group, () => {
api.update(serializer, group, (newGroup) => {
resetForm();
onCreate && onCreate();
onCreate && onCreate(newGroup);
});
} else {
api.create(serializer, new Group(undefined, name, undefined, icon, undefined, parentId, color), () => {
api.create(serializer, new Group(undefined, name, undefined, icon, undefined, parentId, color), (newGroup) => {
resetForm();
onCreate && onCreate();
onCreate && onCreate(newGroup);
});
}
}

View File

@ -44,9 +44,9 @@ export default function GuestFormDialog({ groups, onCreate, onHide, guest, visib
guest.group!.id = group;
guest.status = status;
api.update(serializer, guest, () => {
api.update(serializer, guest, (updatedGuest) => {
resetForm();
onCreate && onCreate(guest);
onCreate && onCreate(updatedGuest);
});
} else {
api.create(serializer, new Guest(undefined, name, undefined, status, [], groups.find((g) => g.id === group)), (newGuest)=> {
@ -62,8 +62,8 @@ export default function GuestFormDialog({ groups, onCreate, onHide, guest, visib
<Dialog header="Add guest" visible={visible} style={{ width: '60vw' }} onHide={onHide}>
<div className="card flex justify-evenly py-5">
<FloatLabel>
<InputText id="username" className='rounded-sm' value={name} onChange={(e) => setName(e.target.value)} />
<label htmlFor="username">Username</label>
<InputText id="name" className='rounded-sm' value={name} onChange={(e) => setName(e.target.value)} />
<label htmlFor="name">Name</label>
</FloatLabel>
<FloatLabel>
<Dropdown id="group" className='rounded-sm min-w-32' value={group} onChange={(e) => setGroup(e.target.value)} options={

View File

@ -13,12 +13,12 @@
"@tiptap/react": "^2.14.0",
"@tiptap/starter-kit": "^2.14.0",
"autoprefixer": "10.4.21",
"bcrypt": "^5.1.1",
"bcrypt": "^6.0.0",
"clsx": "^2.1.1",
"dompurify": "^3.2.6",
"next": "15.3.3",
"next-auth": "5.0.0-beta.28",
"postcss": "8.5.4",
"postcss": "8.5.5",
"primeicons": "^7.0.0",
"primereact": "^10.8.2",
"react": "19.0.0-rc-f38c22b244-20240704",
@ -32,7 +32,7 @@
"devDependencies": {
"@playwright/test": "^1.52.0",
"@types/bcrypt": "^5.0.2",
"@types/node": "22.15.30",
"@types/node": "22.15.31",
"@types/react": "18.3.23",
"@types/react-dom": "18.3.7",
"wait-on": "^8.0.3"

480
pnpm-lock.yaml generated
View File

@ -28,10 +28,10 @@ importers:
version: 2.14.0
autoprefixer:
specifier: 10.4.21
version: 10.4.21(postcss@8.5.4)
version: 10.4.21(postcss@8.5.5)
bcrypt:
specifier: ^5.1.1
version: 5.1.1
specifier: ^6.0.0
version: 6.0.0
clsx:
specifier: ^2.1.1
version: 2.1.1
@ -45,8 +45,8 @@ importers:
specifier: 5.0.0-beta.28
version: 5.0.0-beta.28(next@15.3.3(@playwright/test@1.53.0)(react-dom@19.0.0-rc-f38c22b244-20240704(react@19.0.0-rc-f38c22b244-20240704))(react@19.0.0-rc-f38c22b244-20240704))(react@19.0.0-rc-f38c22b244-20240704)
postcss:
specifier: 8.5.4
version: 8.5.4
specifier: 8.5.5
version: 8.5.5
primeicons:
specifier: ^7.0.0
version: 7.0.0
@ -73,7 +73,7 @@ importers:
version: 11.1.0
zod:
specifier: ^3.23.8
version: 3.25.46
version: 3.25.64
devDependencies:
'@playwright/test':
specifier: ^1.52.0
@ -82,8 +82,8 @@ importers:
specifier: ^5.0.2
version: 5.0.2
'@types/node':
specifier: 22.15.30
version: 22.15.30
specifier: 22.15.31
version: 22.15.31
'@types/react':
specifier: 18.3.23
version: 18.3.23
@ -241,10 +241,6 @@ packages:
cpu: [x64]
os: [win32]
'@mapbox/node-pre-gyp@1.0.11':
resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==}
hasBin: true
'@next/env@15.3.3':
resolution: {integrity: sha512-OdiMrzCl2Xi0VTjiQQUK0Xh7bJHnOuET2s+3V+Y40WJBAXrJeGA3f+I8MZJ/YQ3mVGi5XGR1L66oFlgqXhQ4Vw==}
@ -473,8 +469,8 @@ packages:
'@types/mdurl@2.0.0':
resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==}
'@types/node@22.15.30':
resolution: {integrity: sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA==}
'@types/node@22.15.31':
resolution: {integrity: sha512-jnVe5ULKl6tijxUhvQeNbQG/84fHfg+yMak02cT8QVhBx/F05rAVxCGBYYTh2EKz22D6JF5ktXuNwdx7b9iEGw==}
'@types/prop-types@15.7.12':
resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==}
@ -498,25 +494,6 @@ packages:
'@types/use-sync-external-store@0.0.6':
resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==}
abbrev@1.1.1:
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
agent-base@6.0.2:
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
engines: {node: '>= 6.0.0'}
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
aproba@2.0.0:
resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==}
are-we-there-yet@2.0.0:
resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==}
engines: {node: '>=10'}
deprecated: This package is no longer supported.
argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
@ -533,19 +510,13 @@ packages:
axios@1.9.0:
resolution: {integrity: sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==}
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
bcrypt@5.1.1:
resolution: {integrity: sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==}
engines: {node: '>= 10.0.0'}
bcrypt@6.0.0:
resolution: {integrity: sha512-cU8v/EGSrnH+HnxV2z0J7/blxH8gq7Xh2JFT6Aroax7UohdmiJJlxApMxtKfuI7z68NvvVcmR78k2LbT6efhRg==}
engines: {node: '>= 18'}
bind-event-listener@3.0.0:
resolution: {integrity: sha512-PJvH288AWQhKs2v9zyfYdPzlPqf5bXbGMmhmUIY9x4dAUGIWgomO771oBQNwJnMQSnUIXhKu6sgzpBRXTlvb8Q==}
brace-expansion@1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
browserslist@4.24.4:
resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
@ -562,10 +533,6 @@ packages:
caniuse-lite@1.0.30001702:
resolution: {integrity: sha512-LoPe/D7zioC0REI5W73PeR1e1MLCipRGq/VkovJnd6Df+QVqT+vT33OXCp8QUd7kA7RZrHWxb1B36OQKI/0gOA==}
chownr@2.0.0:
resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
engines: {node: '>=10'}
client-only@0.0.1:
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
@ -583,10 +550,6 @@ packages:
color-string@1.9.1:
resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
color-support@1.1.3:
resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==}
hasBin: true
color@4.2.3:
resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
engines: {node: '>=12.5.0'}
@ -595,34 +558,16 @@ packages:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
console-control-strings@1.1.0:
resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
crelt@1.0.6:
resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==}
csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
debug@4.3.5:
resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==}
engines: {node: '>=6.0'}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
delegates@1.0.0:
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
detect-libc@2.0.3:
resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
engines: {node: '>=8'}
@ -640,9 +585,6 @@ packages:
electron-to-chromium@1.5.113:
resolution: {integrity: sha512-wjT2O4hX+wdWPJ76gWSkMhcHAV2PTMX+QetUCPYEdCIe+cxmgzzSSiGRCKW8nuh4mwKZlpv0xvoW7OF2X+wmHg==}
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
entities@4.5.0:
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
engines: {node: '>=0.12'}
@ -690,13 +632,6 @@ packages:
fraction.js@4.3.7:
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
fs-minipass@2.1.0:
resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==}
engines: {node: '>= 8'}
fs.realpath@1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
fsevents@2.3.2:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@ -705,11 +640,6 @@ packages:
function-bind@1.1.2:
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
gauge@3.0.2:
resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==}
engines: {node: '>=10'}
deprecated: This package is no longer supported.
get-intrinsic@1.3.0:
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
engines: {node: '>= 0.4'}
@ -718,10 +648,6 @@ packages:
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
engines: {node: '>= 0.4'}
glob@7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
deprecated: Glob versions prior to v9 are no longer supported
gopd@1.2.0:
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
engines: {node: '>= 0.4'}
@ -734,31 +660,13 @@ packages:
resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
engines: {node: '>= 0.4'}
has-unicode@2.0.1:
resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
hasown@2.0.2:
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
engines: {node: '>= 0.4'}
https-proxy-agent@5.0.1:
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
engines: {node: '>= 6'}
inflight@1.0.6:
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
inherits@2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
is-arrayish@0.3.2:
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
is-fullwidth-code-point@3.0.0:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
joi@17.13.3:
resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==}
@ -778,10 +686,6 @@ packages:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
make-dir@3.1.0:
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
engines: {node: '>=8'}
markdown-it@14.1.0:
resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==}
hasBin: true
@ -805,32 +709,9 @@ packages:
resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==}
hasBin: true
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
minipass@3.3.6:
resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==}
engines: {node: '>=8'}
minipass@5.0.0:
resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==}
engines: {node: '>=8'}
minizlib@2.1.2:
resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
engines: {node: '>= 8'}
mkdirp@1.0.4:
resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
engines: {node: '>=10'}
hasBin: true
ms@2.1.2:
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
nanoid@3.3.11:
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@ -878,34 +759,21 @@ packages:
sass:
optional: true
node-addon-api@5.1.0:
resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==}
node-addon-api@8.4.0:
resolution: {integrity: sha512-D9DI/gXHvVmjHS08SVch0Em8G5S1P+QWtU31appcKT/8wFSPRcdHadIFSAntdMMVM5zz+/DL+bL/gz3UDppqtg==}
engines: {node: ^18 || ^20 || >= 21}
node-fetch@2.7.0:
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
engines: {node: 4.x || >=6.0.0}
peerDependencies:
encoding: ^0.1.0
peerDependenciesMeta:
encoding:
optional: true
node-gyp-build@4.8.4:
resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==}
hasBin: true
node-releases@2.0.19:
resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==}
nopt@5.0.0:
resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==}
engines: {node: '>=6'}
hasBin: true
normalize-range@0.1.2:
resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
engines: {node: '>=0.10.0'}
npmlog@5.0.1:
resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==}
deprecated: This package is no longer supported.
oauth4webapi@3.5.0:
resolution: {integrity: sha512-DF3mLWNuxPkxJkHmWxbSFz4aE5CjWOsm465VBfBdWzmzX4Mg3vF8icxK+iKqfdWrIumBJ2TaoNQWx+SQc2bsPQ==}
@ -913,16 +781,9 @@ packages:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
once@1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
orderedmap@2.1.1:
resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==}
path-is-absolute@1.0.1:
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
engines: {node: '>=0.10.0'}
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
@ -943,8 +804,8 @@ packages:
resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
engines: {node: ^10 || ^12 || >=14}
postcss@8.5.4:
resolution: {integrity: sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==}
postcss@8.5.5:
resolution: {integrity: sha512-d/jtm+rdNT8tpXuHY5MMtcbJFBkhXE6593XVR9UoGCH8jSFGci7jGvMGH5RYd5PBJW+00NZQt6gf7CbagJCrhg==}
engines: {node: ^10 || ^12 || >=14}
preact-render-to-string@6.5.11:
@ -1058,51 +919,24 @@ packages:
resolution: {integrity: sha512-OP8O6Oc1rdR9IdIKJRKaL1PYd4eGkn6f88VqiygWyyG4P4RmPPix5pp7MatqSt9TnBOcVT+lBMGoVxRgUFeudQ==}
engines: {node: '>=0.10.0'}
readable-stream@3.6.2:
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
engines: {node: '>= 6'}
rimraf@3.0.2:
resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
deprecated: Rimraf versions prior to v4 are no longer supported
hasBin: true
rope-sequence@1.3.4:
resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==}
rxjs@7.8.2:
resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==}
safe-buffer@5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
scheduler@0.25.0-rc-f38c22b244-20240704:
resolution: {integrity: sha512-uAELK9fHhvg7kDQhk29+uO8FUMWUpkg9WpzkNXFP+BJy5HEtqnajde3CxuSgh202WH9TqoaiWT1mdA3DvUu6cQ==}
semver@6.3.1:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
semver@7.6.2:
resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==}
engines: {node: '>=10'}
hasBin: true
semver@7.7.1:
resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==}
engines: {node: '>=10'}
hasBin: true
set-blocking@2.0.0:
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
sharp@0.34.1:
resolution: {integrity: sha512-1j0w61+eVxu7DawFJtnfYcvSv6qPFvfTaqzTQ2BLknVhHTwGS8sc63ZBF4rzkWMBVKybo4S5OBtDdZahh2A1xg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
signal-exit@3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
simple-swizzle@0.2.2:
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
@ -1114,17 +948,6 @@ packages:
resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
engines: {node: '>=10.0.0'}
string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
string_decoder@1.3.0:
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
styled-jsx@5.1.6:
resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==}
engines: {node: '>= 12.0.0'}
@ -1141,16 +964,9 @@ packages:
tailwindcss@4.1.10:
resolution: {integrity: sha512-P3nr6WkvKV/ONsTzj6Gb57sWPMX29EPNPopo7+FcpkQaNsrNpZ1pv8QmrYI2RqEKD7mlGqLnGovlcYnBK0IqUA==}
tar@6.2.1:
resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==}
engines: {node: '>=10'}
tippy.js@6.3.7:
resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==}
tr46@0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
@ -1182,9 +998,6 @@ packages:
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
uuid@11.1.0:
resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==}
hasBin: true
@ -1197,23 +1010,8 @@ packages:
engines: {node: '>=12.0.0'}
hasBin: true
webidl-conversions@3.0.1:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
whatwg-url@5.0.0:
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
wide-align@1.1.5:
resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
yallist@4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
zod@3.25.46:
resolution: {integrity: sha512-IqRxcHEIjqLd4LNS/zKffB3Jzg3NwqJxQQ0Ns7pdrvgGkwQsEBdEQcOHaBVqvvZArShRzI39+aMST3FBGmTrLQ==}
zod@3.25.64:
resolution: {integrity: sha512-hbP9FpSZf7pkS7hRVUrOjhwKJNyampPgtXKc3AN6DsWtoHsg2Sb4SQaS4Tcay380zSwd2VPo9G9180emBACp5g==}
snapshots:
@ -1326,21 +1124,6 @@ snapshots:
'@img/sharp-win32-x64@0.34.1':
optional: true
'@mapbox/node-pre-gyp@1.0.11':
dependencies:
detect-libc: 2.0.3
https-proxy-agent: 5.0.1
make-dir: 3.1.0
node-fetch: 2.7.0
nopt: 5.0.0
npmlog: 5.0.1
rimraf: 3.0.2
semver: 7.6.2
tar: 6.2.1
transitivePeerDependencies:
- encoding
- supports-color
'@next/env@15.3.3': {}
'@next/swc-darwin-arm64@15.3.3':
@ -1552,7 +1335,7 @@ snapshots:
'@types/bcrypt@5.0.2':
dependencies:
'@types/node': 22.15.30
'@types/node': 22.15.31
'@types/linkify-it@5.0.0': {}
@ -1563,7 +1346,7 @@ snapshots:
'@types/mdurl@2.0.0': {}
'@types/node@22.15.30':
'@types/node@22.15.31':
dependencies:
undici-types: 6.21.0
@ -1587,35 +1370,18 @@ snapshots:
'@types/use-sync-external-store@0.0.6': {}
abbrev@1.1.1: {}
agent-base@6.0.2:
dependencies:
debug: 4.3.5
transitivePeerDependencies:
- supports-color
ansi-regex@5.0.1: {}
aproba@2.0.0: {}
are-we-there-yet@2.0.0:
dependencies:
delegates: 1.0.0
readable-stream: 3.6.2
argparse@2.0.1: {}
asynckit@0.4.0: {}
autoprefixer@10.4.21(postcss@8.5.4):
autoprefixer@10.4.21(postcss@8.5.5):
dependencies:
browserslist: 4.24.4
caniuse-lite: 1.0.30001702
fraction.js: 4.3.7
normalize-range: 0.1.2
picocolors: 1.1.1
postcss: 8.5.4
postcss: 8.5.5
postcss-value-parser: 4.2.0
axios@1.9.0:
@ -1626,23 +1392,13 @@ snapshots:
transitivePeerDependencies:
- debug
balanced-match@1.0.2: {}
bcrypt@5.1.1:
bcrypt@6.0.0:
dependencies:
'@mapbox/node-pre-gyp': 1.0.11
node-addon-api: 5.1.0
transitivePeerDependencies:
- encoding
- supports-color
node-addon-api: 8.4.0
node-gyp-build: 4.8.4
bind-event-listener@3.0.0: {}
brace-expansion@1.1.11:
dependencies:
balanced-match: 1.0.2
concat-map: 0.0.1
browserslist@4.24.4:
dependencies:
caniuse-lite: 1.0.30001702
@ -1661,8 +1417,6 @@ snapshots:
caniuse-lite@1.0.30001702: {}
chownr@2.0.0: {}
client-only@0.0.1: {}
clsx@2.1.1: {}
@ -1681,8 +1435,6 @@ snapshots:
simple-swizzle: 0.2.2
optional: true
color-support@1.1.3: {}
color@4.2.3:
dependencies:
color-convert: 2.0.1
@ -1693,23 +1445,14 @@ snapshots:
dependencies:
delayed-stream: 1.0.0
concat-map@0.0.1: {}
console-control-strings@1.1.0: {}
crelt@1.0.6: {}
csstype@3.1.3: {}
debug@4.3.5:
dependencies:
ms: 2.1.2
delayed-stream@1.0.0: {}
delegates@1.0.0: {}
detect-libc@2.0.3: {}
detect-libc@2.0.3:
optional: true
dom-helpers@5.2.1:
dependencies:
@ -1728,8 +1471,6 @@ snapshots:
electron-to-chromium@1.5.113: {}
emoji-regex@8.0.0: {}
entities@4.5.0: {}
es-define-property@1.0.1: {}
@ -1765,29 +1506,11 @@ snapshots:
fraction.js@4.3.7: {}
fs-minipass@2.1.0:
dependencies:
minipass: 3.3.6
fs.realpath@1.0.0: {}
fsevents@2.3.2:
optional: true
function-bind@1.1.2: {}
gauge@3.0.2:
dependencies:
aproba: 2.0.0
color-support: 1.1.3
console-control-strings: 1.1.0
has-unicode: 2.0.1
object-assign: 4.1.1
signal-exit: 3.0.7
string-width: 4.2.3
strip-ansi: 6.0.1
wide-align: 1.1.5
get-intrinsic@1.3.0:
dependencies:
call-bind-apply-helpers: 1.0.2
@ -1806,15 +1529,6 @@ snapshots:
dunder-proto: 1.0.1
es-object-atoms: 1.1.1
glob@7.2.3:
dependencies:
fs.realpath: 1.0.0
inflight: 1.0.6
inherits: 2.0.4
minimatch: 3.1.2
once: 1.4.0
path-is-absolute: 1.0.1
gopd@1.2.0: {}
has-symbols@1.1.0: {}
@ -1823,31 +1537,13 @@ snapshots:
dependencies:
has-symbols: 1.1.0
has-unicode@2.0.1: {}
hasown@2.0.2:
dependencies:
function-bind: 1.1.2
https-proxy-agent@5.0.1:
dependencies:
agent-base: 6.0.2
debug: 4.3.5
transitivePeerDependencies:
- supports-color
inflight@1.0.6:
dependencies:
once: 1.4.0
wrappy: 1.0.2
inherits@2.0.4: {}
is-arrayish@0.3.2:
optional: true
is-fullwidth-code-point@3.0.0: {}
joi@17.13.3:
dependencies:
'@hapi/hoek': 9.3.0
@ -1870,10 +1566,6 @@ snapshots:
dependencies:
js-tokens: 4.0.0
make-dir@3.1.0:
dependencies:
semver: 6.3.1
markdown-it@14.1.0:
dependencies:
argparse: 2.0.1
@ -1895,27 +1587,8 @@ snapshots:
mini-svg-data-uri@1.4.4: {}
minimatch@3.1.2:
dependencies:
brace-expansion: 1.1.11
minimist@1.2.8: {}
minipass@3.3.6:
dependencies:
yallist: 4.0.0
minipass@5.0.0: {}
minizlib@2.1.2:
dependencies:
minipass: 3.3.6
yallist: 4.0.0
mkdirp@1.0.4: {}
ms@2.1.2: {}
nanoid@3.3.11: {}
nanoid@3.3.8: {}
@ -1952,39 +1625,20 @@ snapshots:
- '@babel/core'
- babel-plugin-macros
node-addon-api@5.1.0: {}
node-addon-api@8.4.0: {}
node-fetch@2.7.0:
dependencies:
whatwg-url: 5.0.0
node-gyp-build@4.8.4: {}
node-releases@2.0.19: {}
nopt@5.0.0:
dependencies:
abbrev: 1.1.1
normalize-range@0.1.2: {}
npmlog@5.0.1:
dependencies:
are-we-there-yet: 2.0.0
console-control-strings: 1.1.0
gauge: 3.0.2
set-blocking: 2.0.0
oauth4webapi@3.5.0: {}
object-assign@4.1.1: {}
once@1.4.0:
dependencies:
wrappy: 1.0.2
orderedmap@2.1.1: {}
path-is-absolute@1.0.1: {}
picocolors@1.1.1: {}
playwright-core@1.53.0: {}
@ -2003,7 +1657,7 @@ snapshots:
picocolors: 1.1.1
source-map-js: 1.2.1
postcss@8.5.4:
postcss@8.5.5:
dependencies:
nanoid: 3.3.11
picocolors: 1.1.1
@ -2159,35 +1813,17 @@ snapshots:
react@19.0.0-rc-f38c22b244-20240704: {}
readable-stream@3.6.2:
dependencies:
inherits: 2.0.4
string_decoder: 1.3.0
util-deprecate: 1.0.2
rimraf@3.0.2:
dependencies:
glob: 7.2.3
rope-sequence@1.3.4: {}
rxjs@7.8.2:
dependencies:
tslib: 2.8.1
safe-buffer@5.2.1: {}
scheduler@0.25.0-rc-f38c22b244-20240704: {}
semver@6.3.1: {}
semver@7.6.2: {}
semver@7.7.1:
optional: true
set-blocking@2.0.0: {}
sharp@0.34.1:
dependencies:
color: 4.2.3
@ -2216,8 +1852,6 @@ snapshots:
'@img/sharp-win32-x64': 0.34.1
optional: true
signal-exit@3.0.7: {}
simple-swizzle@0.2.2:
dependencies:
is-arrayish: 0.3.2
@ -2227,20 +1861,6 @@ snapshots:
streamsearch@1.1.0: {}
string-width@4.2.3:
dependencies:
emoji-regex: 8.0.0
is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1
string_decoder@1.3.0:
dependencies:
safe-buffer: 5.2.1
strip-ansi@6.0.1:
dependencies:
ansi-regex: 5.0.1
styled-jsx@5.1.6(react@19.0.0-rc-f38c22b244-20240704):
dependencies:
client-only: 0.0.1
@ -2248,21 +1868,10 @@ snapshots:
tailwindcss@4.1.10: {}
tar@6.2.1:
dependencies:
chownr: 2.0.0
fs-minipass: 2.1.0
minipass: 5.0.0
minizlib: 2.1.2
mkdirp: 1.0.4
yallist: 4.0.0
tippy.js@6.3.7:
dependencies:
'@popperjs/core': 2.11.8
tr46@0.0.3: {}
tslib@2.8.1: {}
typescript@5.8.3: {}
@ -2285,8 +1894,6 @@ snapshots:
dependencies:
react: 19.0.0-rc-f38c22b244-20240704
util-deprecate@1.0.2: {}
uuid@11.1.0: {}
w3c-keyname@2.2.8: {}
@ -2301,19 +1908,4 @@ snapshots:
transitivePeerDependencies:
- debug
webidl-conversions@3.0.1: {}
whatwg-url@5.0.0:
dependencies:
tr46: 0.0.3
webidl-conversions: 3.0.1
wide-align@1.1.5:
dependencies:
string-width: 4.2.3
wrappy@1.0.2: {}
yallist@4.0.0: {}
zod@3.25.46: {}
zod@3.25.64: {}

65
tests/groups.spec.ts Normal file
View File

@ -0,0 +1,65 @@
import { test, expect, Page } from '@playwright/test'
import mockGroupsAPI from './mocks/groups';
import mockGuestsAPI from './mocks/guests';
test('should allow CRUD on groups', async ({ page }) => {
await mockGuestsAPI({ page });
await mockGroupsAPI({ page });
await page.goto('/default/dashboard/guests');
await page.getByRole('tab', { name: 'Groups' }).click();
await expect(page.getByRole('button', { name: 'Add new' })).toBeVisible();
await expect(page.getByRole('button', { name: 'Reset affinities' })).toBeVisible();
// List all groups
await expect(page.getByRole('row')).toHaveCount(3); // 1 header row + 2 data rows
await expect(page.getByRole('row').nth(0).getByRole('columnheader').nth(0)).toHaveText('Name');
await expect(page.getByRole('row').nth(0).getByRole('columnheader').nth(1)).toHaveText('Color');
await expect(page.getByRole('row').nth(0).getByRole('columnheader').nth(2)).toHaveText('Confirmed');
await expect(page.getByRole('row').nth(0).getByRole('columnheader').nth(3)).toHaveText('Tentative');
await expect(page.getByRole('row').nth(0).getByRole('columnheader').nth(4)).toHaveText('Pending');
await expect(page.getByRole('row').nth(0).getByRole('columnheader').nth(5)).toHaveText('Declined');
await expect(page.getByRole('row').nth(0).getByRole('columnheader').nth(6)).toHaveText('Considered');
await expect(page.getByRole('row').nth(0).getByRole('columnheader').nth(7)).toHaveText('Total');
await expect(page.getByRole('row').nth(0).getByRole('columnheader').nth(8)).toHaveText('Actions');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(0)).toContainText('Pam\'s family');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(2)).toHaveText('0');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(3)).toHaveText('0');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(4)).toHaveText('1');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(5)).toHaveText('0');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(6)).toHaveText('2');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(7)).toHaveText('3');
await expect(page.getByRole('row').nth(1).locator('svg:visible')).toHaveCount(3);
await expect(page.getByRole('row').nth(2).getByRole('cell').nth(0)).toContainText('Pam\'s work');
await expect(page.getByRole('row').nth(2).getByRole('cell').nth(2)).toHaveText('0');
await expect(page.getByRole('row').nth(2).getByRole('cell').nth(3)).toHaveText('2');
await expect(page.getByRole('row').nth(2).getByRole('cell').nth(4)).toHaveText('0');
await expect(page.getByRole('row').nth(2).getByRole('cell').nth(5)).toHaveText('0');
await expect(page.getByRole('row').nth(2).getByRole('cell').nth(6)).toHaveText('0');
await expect(page.getByRole('row').nth(2).getByRole('cell').nth(7)).toHaveText('2');
await expect(page.getByRole('row').nth(2).locator('svg:visible')).toHaveCount(3);
// Add a new group
await page.getByRole('button', { name: 'Add new' }).click();
const dialog = page.getByRole('dialog');
await expect(dialog).toBeVisible();
await dialog.getByLabel('Name').fill("Pam's friends");
await dialog.getByRole('button', { name: 'Create' }).click();
await expect(dialog).not.toBeVisible();
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(0)).toContainText('Pam\'s friends');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(2)).toHaveText('0');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(3)).toHaveText('0');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(4)).toHaveText('0');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(5)).toHaveText('0');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(6)).toHaveText('0');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(7)).toHaveText('0');
await expect(page.getByRole('row').nth(1).locator('svg:visible')).toHaveCount(3);
});

View File

@ -1,88 +1,10 @@
import { test, expect, Page } from '@playwright/test'
import { mock } from 'node:test';
import { expect, test } from '@playwright/test';
import mockGroupsAPI from './mocks/groups';
import mockGuestsAPI from './mocks/guests';
const mockGuestsAPI = ({ page }: { page: Page }) => {
page.route('*/**/api/default/guests', async route => {
if (route.request().method() === 'GET') {
const json = [
{
"id": "f4a09c28-40ea-4553-90a5-96935a59cac6",
"status": "tentative",
"name": "Kristofer Rohan DVM",
"group": {
"id": "2fcb8b22-6b07-4c34-92e3-a2535dbc5b14",
"name": "Childhood friends",
}
},
{
"id": "bd585c40-0937-4cde-960a-bb23acfd6f18",
"status": "invited",
"name": "Olevia Quigley Jr.",
"group": {
"id": "da8edf26-3e1e-4cbb-b985-450c49fffe01",
"name": "Work",
}
},
];
await route.fulfill({ json })
} else if (route.request().method() === 'POST') {
const json = {
"id":"ff58aa2d-643d-4c29-be9c-50e10ae6853c",
"name":"John Snow",
"status":"invited",
"group": {
"id": "da8edf26-3e1e-4cbb-b985-450c49fffe01",
"name": "Work",
}
};
await route.fulfill({ json });
}
})
}
const mockGroupsAPI = ({ page }: { page: Page }) => {
page.route('*/**/api/default/groups', async route => {
const json = [
{
"id": "ee44ffb9-1147-4842-a378-9eaeb0f0871a",
"name": "Pam's family",
"icon": "pi pi-users",
"parent_id": null,
"color": "#ff0000",
"attendance": {
"total": 3,
"considered": 2,
"invited": 1,
"confirmed": 0,
"declined": 0,
"tentative": 0
}
},
{
"id": "c8bda6ca-d8af-4bb8-b2bf-e6ec1c21b1e6",
"name": "Pam's work",
"icon": "pi pi-desktop",
"parent_id": null,
"color": "#00ff00",
"attendance": {
"total": 2,
"considered": 0,
"invited": 0,
"confirmed": 0,
"declined": 0,
"tentative": 2
}
},
];
await route.fulfill({ json })
})
}
test('should display the list of guests', async ({ page }) => {
test('should allow CRUD on guests', async ({ page }) => {
await mockGuestsAPI({ page });
await mockGroupsAPI({ page });
await page.goto('/default/dashboard/guests');
@ -92,89 +14,62 @@ test('should display the list of guests', async ({ page }) => {
await expect(page.getByRole('tab', { name: 'Groups' })).toBeVisible();
await expect(page.getByRole('tab', { name: 'Invitations' })).toBeVisible();
// List all guests
await expect(page.getByText('There are 2 elements in the list')).toBeVisible();
await expect(page.getByRole('row')).toHaveCount(3); // 1 header row + 2 data rows
await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'Kristofer Rohan DVM' })).toBeVisible();
await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'Childhood friends' })).toBeVisible();
await expect(page.getByRole('row').nth(1).getByRole('cell', { name: "Pam's family" })).toBeVisible();
await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'Tentative' })).toBeVisible();
await expect(page.getByRole('row').nth(1).locator('svg')).toHaveCount(2);
await expect(page.getByRole('row').nth(2).getByRole('cell', { name: 'Olevia Quigley Jr.' })).toBeVisible();
await expect(page.getByRole('row').nth(2).getByRole('cell', { name: 'Work' })).toBeVisible();
await expect(page.getByRole('row').nth(2).getByRole('cell', { name: "Pam's work" })).toBeVisible();
await expect(page.getByRole('row').nth(2).getByRole('cell', { name: 'Invited' })).toBeVisible();
await expect(page.getByRole('row').nth(2).locator('svg')).toHaveCount(2);
});
test('should allow creating a new guest', async ({ page }) => {
await mockGuestsAPI({ page });
await mockGroupsAPI({ page });
await page.goto('/default/dashboard/guests');
await expect(page.getByText('There are 2 elements in the list')).toBeVisible();
// Add a new guest
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByRole('dialog').getByLabel('Name').fill('John Snow');
await page.keyboard.press('Tab');
await page.keyboard.press('ArrowDown');
await page.keyboard.press('ArrowDown');
await page.keyboard.press('Enter');
await page.locator('#group').click();
await page.getByRole('option', { name: "Pam's work" }).click();
await page.keyboard.press('Tab');
await page.keyboard.press('ArrowDown');
await page.keyboard.press('ArrowDown');
await page.keyboard.press('Enter');
await page.locator('#status').click();
await page.getByRole('option', { name: 'Invited' }).click();
await page.getByRole('dialog').getByRole('button', { name: 'Create' }).click();
await expect(page.getByText('There are 3 elements in the list')).toBeVisible();
await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'John Snow' })).toBeVisible();
await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'Work' })).toBeVisible();
await expect(page.getByRole('row').nth(1).getByRole('cell', { name: "Pam\'s work" })).toBeVisible();
await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'Invited' })).toBeVisible();
await expect(page.getByRole('row').nth(1).locator('svg')).toHaveCount(2);
});
test('should display the list of groups', async ({ page }) => {
await mockGroupsAPI({ page });
await page.goto('/default/dashboard/guests');
await page.getByRole('tab', { name: 'Groups' }).click();
await expect(page.getByRole('button', { name: 'Add new' })).toBeVisible();
await expect(page.getByRole('button', { name: 'Reset affinities' })).toBeVisible();
await expect(page.getByRole('row')).toHaveCount(3); // 1 header row + 2 data rows
await expect(page.getByRole('row').nth(0).getByRole('columnheader').nth(0)).toHaveText('Name');
await expect(page.getByRole('row').nth(0).getByRole('columnheader').nth(1)).toHaveText('Color');
await expect(page.getByRole('row').nth(0).getByRole('columnheader').nth(2)).toHaveText('Confirmed');
await expect(page.getByRole('row').nth(0).getByRole('columnheader').nth(3)).toHaveText('Tentative');
await expect(page.getByRole('row').nth(0).getByRole('columnheader').nth(4)).toHaveText('Pending');
await expect(page.getByRole('row').nth(0).getByRole('columnheader').nth(5)).toHaveText('Declined');
await expect(page.getByRole('row').nth(0).getByRole('columnheader').nth(6)).toHaveText('Considered');
await expect(page.getByRole('row').nth(0).getByRole('columnheader').nth(7)).toHaveText('Total');
await expect(page.getByRole('row').nth(0).getByRole('columnheader').nth(8)).toHaveText('Actions');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(0)).toContainText('Pam\'s family');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(2)).toHaveText('0');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(3)).toHaveText('0');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(4)).toHaveText('1');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(5)).toHaveText('0');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(6)).toHaveText('2');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(7)).toHaveText('3');
await expect(page.getByRole('row').nth(1).locator('svg:visible')).toHaveCount(3);
await expect(page.getByRole('row').nth(2).getByRole('cell').nth(0)).toContainText('Pam\'s work');
await expect(page.getByRole('row').nth(2).getByRole('cell').nth(2)).toHaveText('0');
await expect(page.getByRole('row').nth(2).getByRole('cell').nth(3)).toHaveText('2');
await expect(page.getByRole('row').nth(2).getByRole('cell').nth(4)).toHaveText('0');
await expect(page.getByRole('row').nth(2).getByRole('cell').nth(5)).toHaveText('0');
await expect(page.getByRole('row').nth(2).getByRole('cell').nth(6)).toHaveText('0');
await expect(page.getByRole('row').nth(2).getByRole('cell').nth(7)).toHaveText('2');
await expect(page.getByRole('row').nth(2).locator('svg:visible')).toHaveCount(3);
// Edit the just-added John Snow
await page.getByRole('row').nth(1).locator('svg').nth(1).click(); // Click edit icon
const dialog = page.getByRole('dialog');
await expect(dialog.getByLabel('Name')).toHaveValue('John Snow');
await dialog.getByLabel('Name').fill('John Fire');
await dialog.locator('#group').click();
await page.getByRole('option', { name: "Pam's family" }).click();
await dialog.locator('#status').click();
await page.getByRole('option', { name: 'Declined' }).click();
await dialog.getByRole('button', { name: 'Update' }).click();
await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'John Fire' })).toBeVisible();
await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'Pam\'s Family' })).toBeVisible();
await expect(page.getByRole('row').nth(1).getByRole('cell', { name: 'Declined' })).toBeVisible();
await expect(page.getByText('There are 3 elements in the list')).toBeVisible();
// Delete John Fire
await page.getByRole('row').nth(1).locator('svg').nth(0).click(); // Click delete icon
await expect(page.getByText('There are 2 elements in the list')).toBeVisible();
});

60
tests/mocks/groups.tsx Normal file
View File

@ -0,0 +1,60 @@
import { Page } from "@playwright/test";
export default async function mockGroupsAPI({ page }: { page: Page }): Promise<void> {
page.route('*/**/api/default/groups', async route => {
if (route.request().method() === 'GET') {
const json = [
{
"id": "ee44ffb9-1147-4842-a378-9eaeb0f0871a",
"name": "Pam's family",
"icon": "pi pi-users",
"parent_id": null,
"color": "#ff0000",
"attendance": {
"total": 3,
"considered": 2,
"invited": 1,
"confirmed": 0,
"declined": 0,
"tentative": 0
}
},
{
"id": "c8bda6ca-d8af-4bb8-b2bf-e6ec1c21b1e6",
"name": "Pam's work",
"icon": "pi pi-desktop",
"parent_id": null,
"color": "#00ff00",
"attendance": {
"total": 2,
"considered": 0,
"invited": 0,
"confirmed": 0,
"declined": 0,
"tentative": 2
}
},
];
await route.fulfill({ json })
} else if (route.request().method() === 'POST') {
const json = {
"id": "4d55bc34-6f42-4e2e-82a1-71ae32da2466",
"name": "Pam's friends",
"icon": "pi pi-desktop",
"parent_id": null,
"color": "#0000ff",
"attendance": {
"total": 0,
"considered": 0,
"invited": 0,
"confirmed": 0,
"declined": 0,
"tentative": 0
}
}
await route.fulfill({ json })
}
})
}

61
tests/mocks/guests.tsx Normal file
View File

@ -0,0 +1,61 @@
import { Page } from "@playwright/test";
export default async function mockGuestsAPI({ page }: { page: Page }): Promise<void> {
page.route('*/**/api/default/guests', async route => {
if (route.request().method() === 'GET') {
const json = [
{
"id": "f4a09c28-40ea-4553-90a5-96935a59cac6",
"status": "tentative",
"name": "Kristofer Rohan DVM",
"group": {
"id": "ee44ffb9-1147-4842-a378-9eaeb0f0871a",
"name": "Pam's family",
}
},
{
"id": "bd585c40-0937-4cde-960a-bb23acfd6f18",
"status": "invited",
"name": "Olevia Quigley Jr.",
"group": {
"id": "c8bda6ca-d8af-4bb8-b2bf-e6ec1c21b1e6",
"name": "Pam's work",
}
},
];
await route.fulfill({ json })
} else if (route.request().method() === 'POST') {
const json = {
"id": "ff58aa2d-643d-4c29-be9c-50e10ae6853c",
"name": "John Snow",
"status": "invited",
"group": {
"id": "c8bda6ca-d8af-4bb8-b2bf-e6ec1c21b1e6",
"name": "Pam's work",
}
};
await route.fulfill({ json });
}
})
page.route("*/**/api/default/guests/*", async route => {
if (route.request().method() === 'PUT') {
const json = {
"id": "ff58aa2d-643d-4c29-be9c-50e10ae6853c",
"name": "John Fire",
"status": "declined",
"group": {
"id": "ee44ffb9-1147-4842-a378-9eaeb0f0871a",
"name": "Pam's family",
}
}
await route.fulfill({ json });
} else if (route.request().method() === 'DELETE') {
const json = {}
await route.fulfill({ json });
}
});
}