diff --git a/.gitignore b/.gitignore index f55a550..4339447 100644 --- a/.gitignore +++ b/.gitignore @@ -35,7 +35,5 @@ content/output/* public/content/output/* public/content/output/shifts 2024.1.json !public/content/uploads/* -shift_generate_log_*.txt -.aider.input.history -.aider.chat.history.md -.aider.tags.cache.v3/* +.aider* +/shift_generate_log_*.txt diff --git a/_deploy/entrypoint.sh b/_deploy/entrypoint.sh index 963c99f..81d1d76 100644 --- a/_deploy/entrypoint.sh +++ b/_deploy/entrypoint.sh @@ -39,6 +39,8 @@ if [ "$UPDATE_CODE_FROM_GIT" = "true" ]; then rsync -av --itemize-changes \ --exclude='package.json' \ --exclude='package-lock.json' \ + --exclude='/public/content/permits' \ + --exclude='/public/content/uploads' \ /tmp/clone/ /app/ >> /app/logs/deploy.txt 2>&1 # Check rsync exit status diff --git a/_doc/notes.mb b/_doc/notes.mb index 1236258..e6ed6a4 100644 --- a/_doc/notes.mb +++ b/_doc/notes.mb @@ -118,6 +118,11 @@ next start export OPENAI_API_KEY=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 # personal export OPENAI_API_KEY=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 # dev-bro + aider --openai-api-key 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 --no-auto-commits -- + + ## build - prod +npx run build +npm run prod # ----------------------------------------------update PRISMA schema/sync database ----------------------------------------------- # # prisma migrate dev --create-only NODE_ENV=production npx prisma migrate deploy diff --git a/components/calendar/avcalendar.tsx b/components/calendar/avcalendar.tsx index f83f238..e5e5ebc 100644 --- a/components/calendar/avcalendar.tsx +++ b/components/calendar/avcalendar.tsx @@ -51,10 +51,15 @@ const messages = { const AvCalendar = ({ publisherId, events, selectedDate, cartEvents, lastPublishedDate }) => { const [editLockedBefore, setEditLockedBefore] = useState(new Date(lastPublishedDate)); const [isAdmin, setIsAdmin] = useState(false); + // const [isPowerUser, setIsPowerUser] = useState(false); + // const [currentUserId, setCurrentUserId] = useState(null); useEffect(() => { (async () => { try { setIsAdmin(await ProtectedRoute.IsInRole(UserRole.ADMIN)); + // setIsPowerUser(await ProtectedRoute.IsInRole(UserRole.POWERUSER)); + // // Assuming you have a way to get the current user's ID + // setCurrentUserId(await ProtectedRoute.GetCurrentUserId()); } catch (error) { console.error("Failed to check admin role:", error); } @@ -256,7 +261,9 @@ const AvCalendar = ({ publisherId, events, selectedDate, cartEvents, lastPublish const enddate = common.setTimezone(end); if (!start || !end) return; - //readonly for past dates (ToDo: if not admin) + //readonly for past dates (ToDo: if not admin or current user) + //const isCurrentUser = selectedEvents.some(event => event.userId === currentUserId); + if (!isAdmin) { if (startdate < new Date() || end < new Date() || startdate > end) return; //or if schedule is published (lastPublishedDate) diff --git a/components/protectedRoute.tsx b/components/protectedRoute.tsx index 102e2a1..d77d107 100644 --- a/components/protectedRoute.tsx +++ b/components/protectedRoute.tsx @@ -85,5 +85,10 @@ export async function serverSideAuth({ req, allowedRoles }) { // Static method to check if the user has a specific role ProtectedRoute.IsInRole = async (roleName) => { const session = await getSession(); - return session && session.user && session.user.role === roleName; -}; \ No newline at end of file + return (session && session.user && session.user.role === roleName) || false; +}; + +ProtectedRoute.GetCurrentUserId = async () => { + const session = await getSession(); + return session && session.user && session.user.id; +} \ No newline at end of file diff --git a/components/publisher/PublisherCard.js b/components/publisher/PublisherCard.js index 1b01dd5..0f8c156 100644 --- a/components/publisher/PublisherCard.js +++ b/components/publisher/PublisherCard.js @@ -1,5 +1,5 @@ import Link from "next/link"; -import { Publisher } from "@prisma/client" +import { Publisher, UserRole } from "@prisma/client" // import {IsDateXMonthsAgo} from "../../helpers/const" import { useEffect, useState } from 'react' import toast from "react-hot-toast"; @@ -97,26 +97,27 @@ export default function PublisherCard({ publisher }) {
- + setIsModalOpen(false)} + onConfirm={() => handleDelete(publisher.id)} + message="Сигурни ли сте, че искате да изтриете този профил? Това действие не може да бъде отменено." + /> + +
diff --git a/components/publisher/PublisherForm.js b/components/publisher/PublisherForm.js index 85cdb6f..7f67d22 100644 --- a/components/publisher/PublisherForm.js +++ b/components/publisher/PublisherForm.js @@ -317,7 +317,7 @@ export default function PublisherForm({ item, me }) { {/* ADMINISTRATORS ONLY */} - +
{/* prompt to install PWA */}
@@ -341,12 +341,16 @@ export default function PublisherForm({ item, me }) {
+ + + + + - - +
@@ -356,7 +360,9 @@ export default function PublisherForm({ item, me }) { - + + + {/* Add other roles as needed */}
diff --git a/components/publisher/PublisherShiftsModal.js b/components/publisher/PublisherShiftsModal.js index d8d1bd7..167ed55 100644 --- a/components/publisher/PublisherShiftsModal.js +++ b/components/publisher/PublisherShiftsModal.js @@ -1,17 +1,22 @@ -import React, { useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; import Link from 'next/link'; import common from 'src/helpers/common'; import axiosInstance from 'src/axiosSecure'; const PublisherShiftsModal = ({ publisher, _shifts, onClose, date, onAssignmentChange }) => { - const [shifts, setShifts] = React.useState([..._shifts]); + const [shifts, setShifts] = useState([..._shifts]); + const [assignments, setAssignments] = useState(publisher.assignments || []); //Refactor ToDo: show the whole month instead of just the current week by showing the shift start time in front of the rows, and show all shifts in the month from the first to the last week in the cell where we show one shift now - const monthInfo = common.getMonthDatesInfo(new Date(date)); + let monthInfo = common.getMonthDatesInfo(new Date(date)); + //if date is before monthInfo.firstMonday, get the previous month indexOf + if (date < monthInfo.firstMonday) { + monthInfo = common.getMonthDatesInfo(new Date(date.getFullYear(), date.getMonth() - 1, 1)); + } const monthShifts = shifts.filter(shift => { const shiftDate = new Date(shift.startTime); - return shiftDate > monthInfo.firstDay && shiftDate < monthInfo.lastDay; + return shiftDate > monthInfo.firstDay && shiftDate < monthInfo.lastSunday; }); const weekShifts = monthShifts.filter(shift => { const shiftDate = new Date(shift.startTime); @@ -38,11 +43,13 @@ const PublisherShiftsModal = ({ publisher, _shifts, onClose, date, onAssignmentC console.log("dayShifts:", dayShifts); const hasAssignment = (shiftId) => { - // return publisher.assignments.some(ass => ass.shift.id == shiftId); - return publisher.assignments?.some(ass => { - //console.log(`Comparing: ${ass.shift.id} to ${shiftId}: ${ass.shift.id === shiftId}`); - return ass.shift.id === shiftId; - }); + + return assignments.some(ass => ass.shift.id === shiftId); + // // return publisher.assignments.some(ass => ass.shift.id == shiftId); + // return publisher.assignments?.some(ass => { + // //console.log(`Comparing: ${ass.shift.id} to ${shiftId}: ${ass.shift.id === shiftId}`); + // return ass.shift.id === shiftId; + // }); }; @@ -63,6 +70,61 @@ const PublisherShiftsModal = ({ publisher, _shifts, onClose, date, onAssignmentC }; }, [onClose]); // Include onClose in the dependency array + function getColorForShift(shift) { + const assignedCount = shift.assignedCount || 0; // Assuming each shift has an assignedCount property + switch (assignedCount) { + case 0: return 'bg-blue-300'; + case 1: return 'bg-green-300'; + case 2: return 'bg-yellow-300'; + case 3: return 'bg-orange-300'; + case 4: return 'bg-red-200'; + default: return 'bg-gray-300'; + } + } + + //ToDo: DRY - move to common + const addAssignment = async (publisher, shiftId) => { + try { + console.log(`calendar.idx: new assignment for publisher ${publisher.id} - ${publisher.firstName} ${publisher.lastName}`); + const newAssignment = { + publisher: { connect: { id: publisher.id } }, + shift: { connect: { id: shiftId } }, + isConfirmed: true + }; + const { data } = await axiosInstance.post("/api/data/assignments", newAssignment); + + // Update the 'publisher' property of the returned data with the full publisher object + data.publisher = publisher; + data.shift = shifts.find(shift => shift.id === shiftId); + publisher.assignments = [...publisher.assignments, data]; + // handleAssignmentChange(publisher.id, 'add'); + + setAssignments(prevAssignments => [...prevAssignments, data]); + if (onAssignmentChange) { onAssignmentChange(publisher.id, 'add'); } + } catch (error) { + console.error("Error adding assignment:", error); + } + }; + const removeAssignment = async (publisher, shiftId) => { + try { + const assignment = publisher.assignments.find(ass => ass.shift.id === shiftId); + console.log(`calendar.idx: remove assignment for shift ${shiftId}`); + const { data } = await axiosInstance.delete(`/api/data/assignments/${assignment.id}`); + //remove from local assignments: + publisher.assignments = publisher.assignments.filter(a => a.id !== assignment.id) + // Update local state + setAssignments(prevAssignments => prevAssignments.filter(a => a.id !== assignment.id)); + + // + // handleAssignmentChange(publisher.id, 'remove') + if (onAssignmentChange) { + onAssignmentChange(publisher.id, 'remove') + } + } catch (error) { + console.error("Error removing assignment:", error); + } + } + return (
@@ -91,24 +153,23 @@ const PublisherShiftsModal = ({ publisher, _shifts, onClose, date, onAssignmentC > {common.getTimeRange(shift.startTime, shift.endTime)} {shift.id} - {!assignmentExists && shift.isAvailable && ( - - )} - {assignmentExists && ( - )}
); - } - )} + })}
))}
@@ -133,57 +194,10 @@ const PublisherShiftsModal = ({ publisher, _shifts, onClose, date, onAssignmentC ); + + } -function getColorForShift(shift) { - const assignedCount = shift.assignedCount || 0; // Assuming each shift has an assignedCount property - switch (assignedCount) { - case 0: return 'bg-blue-300'; - case 1: return 'bg-green-300'; - case 2: return 'bg-yellow-300'; - case 3: return 'bg-orange-300'; - case 4: return 'bg-red-200'; - default: return 'bg-gray-300'; - } -} - -//ToDo: DRY - move to common -const addAssignment = async (publisher, shiftId) => { - try { - console.log(`calendar.idx: new assignment for publisher ${publisher.id} - ${publisher.firstName} ${publisher.lastName}`); - const newAssignment = { - publisher: { connect: { id: publisher.id } }, - shift: { connect: { id: shiftId } }, - isConfirmed: true - }; - const { data } = await axiosInstance.post("/api/data/assignments", newAssignment); - - // Update the 'publisher' property of the returned data with the full publisher object - data.publisher = publisher; - data.shift = shifts.find(shift => shift.id === shiftId); - publisher.assignments = [...publisher.assignments, data]; - // handleAssignmentChange(publisher.id, 'add'); - if (onAssignmentChange) { onAssignmentChange(publisher.id, 'add'); } - } catch (error) { - console.error("Error adding assignment:", error); - } -}; -const removeAssignment = async (publisher, shiftId) => { - try { - const assignment = publisher.assignments.find(ass => ass.shift.id === shiftId); - console.log(`calendar.idx: remove assignment for shift ${shiftId}`); - const { data } = await axiosInstance.delete(`/api/data/assignments/${assignment.id}`); - //remove from local assignments: - publisher.assignments = publisher.assignments.filter(a => a.id !== assignment.id) - // - // handleAssignmentChange(publisher.id, 'remove') - if (onAssignmentChange) { - onAssignmentChange(publisher.id, 'remove') - } - } catch (error) { - console.error("Error removing assignment:", error); - } -} export default PublisherShiftsModal; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 23d9ba7..0303b62 100644 --- a/package-lock.json +++ b/package-lock.json @@ -100,6 +100,7 @@ "devDependencies": { "cross-env": "^7.0.3", "depcheck": "^1.4.7", + "eslint-plugin-no-unsanitized": "^4.1.0", "prisma": "^5.19.1" } }, @@ -2128,6 +2129,200 @@ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "peer": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", + "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", + "dev": true, + "peer": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "dev": true, + "peer": true, + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "peer": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/config-array/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "peer": true + }, + "node_modules/@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "dev": true, + "peer": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "peer": true + }, + "node_modules/@eslint/eslintrc/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "peer": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "peer": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "peer": true + }, + "node_modules/@eslint/js": { + "version": "9.10.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz", + "integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==", + "dev": true, + "peer": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "dev": true, + "peer": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.1.0.tgz", + "integrity": "sha512-autAXT203ixhqei9xt+qkYOvY8l6LAFIdT2UXc/RPNeUVfqRF1BV94GTJyVPFKT8nFM6MyVJhjLj9E8JWvf5zQ==", + "dev": true, + "peer": true, + "dependencies": { + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@fast-csv/format": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/@fast-csv/format/-/format-4.3.5.tgz", @@ -2293,6 +2488,34 @@ "react": ">= 16" } }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", + "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "dev": true, + "peer": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@img/sharp-darwin-arm64": { "version": "0.33.2", "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.2.tgz", @@ -4914,9 +5137,9 @@ } }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "bin": { "acorn": "bin/acorn" }, @@ -4933,6 +5156,16 @@ "acorn": "^8" } }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peer": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/acorn-walk": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", @@ -6616,6 +6849,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "peer": true + }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", @@ -7499,6 +7739,75 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint": { + "version": "9.10.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.10.0.tgz", + "integrity": "sha512-Y4D0IgtBZfOcOUAIQTSXBKoNGfY0REGqHJG6+Q81vNippW5YlKjHFj4soMxamKK1NXHUWuBZTLdU3Km+L/pcHw==", + "dev": true, + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.18.0", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.10.0", + "@eslint/plugin-kit": "^0.1.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.3.0", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.0.2", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-no-unsanitized": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-unsanitized/-/eslint-plugin-no-unsanitized-4.1.0.tgz", + "integrity": "sha512-9A8Yrbkkex8e56ivxJ2f5dXN2Js2BmKC8QgmeYZjadyiGUngo3KLXDlq6ZzalmCHyLwLF5MoQLPR6FWlNc+Qbw==", + "dev": true, + "peerDependencies": { + "eslint": "^8 || ^9" + } + }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -7512,6 +7821,178 @@ "node": ">=8.0.0" } }, + "node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true, + "peer": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "peer": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", + "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", + "dev": true, + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "peer": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "peer": true + }, + "node_modules/eslint/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "peer": true + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/espree": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", + "dev": true, + "peer": true, + "dependencies": { + "acorn": "^8.12.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -7525,6 +8006,29 @@ "node": ">=4" } }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "peer": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4.0" + } + }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -7807,6 +8311,13 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "peer": true + }, "node_modules/fast-write-atomic": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fast-write-atomic/-/fast-write-atomic-0.2.1.tgz", @@ -7839,6 +8350,19 @@ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.3.11.tgz", "integrity": "sha512-Rr5QlUeGN1mbOHlaqcSYMKVpPbgLy0AWT/W0EHxA6NGI12yO1jpoui2zBBvU2G824ltM6Ut8BFgfHSBGfkmS0A==" }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "peer": true, + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/file-stream-rotator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz", @@ -7935,7 +8459,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "optional": true, + "devOptional": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -7962,6 +8486,27 @@ "node": ">= 10.13.0" } }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "peer": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true, + "peer": true + }, "node_modules/fn.name": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", @@ -9157,6 +9702,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.8.19" + } + }, "node_modules/indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", @@ -9533,7 +10088,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "optional": true, + "devOptional": true, "engines": { "node": ">=8" } @@ -9881,6 +10436,13 @@ "bignumber.js": "^9.0.0" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "peer": true + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -9896,6 +10458,13 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "peer": true + }, "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -10052,6 +10621,16 @@ "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "peer": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kleur": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", @@ -10133,6 +10712,20 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "peer": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/lie": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", @@ -10185,7 +10778,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "optional": true, + "devOptional": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -10887,6 +11480,13 @@ "node": "^18 || >=20" } }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "peer": true + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -14560,6 +15160,24 @@ "url": "https://github.com/sponsors/panva" } }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "peer": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/p-filter": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", @@ -14585,7 +15203,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "optional": true, + "devOptional": true, "dependencies": { "yocto-queue": "^0.1.0" }, @@ -14600,7 +15218,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "optional": true, + "devOptional": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -15072,6 +15690,16 @@ "preact": ">=10" } }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", @@ -16934,6 +17562,19 @@ "node": ">=8" } }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/styled-jsx": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", @@ -17491,6 +18132,13 @@ "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "peer": true + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -17862,6 +18510,19 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "peer": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", @@ -18631,6 +19292,16 @@ "node": ">=0.8" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", @@ -19352,7 +20023,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "optional": true, + "devOptional": true, "engines": { "node": ">=10" }, diff --git a/package.json b/package.json index 2118700..c38da2e 100644 --- a/package.json +++ b/package.json @@ -118,6 +118,7 @@ "devDependencies": { "cross-env": "^7.0.3", "depcheck": "^1.4.7", + "eslint-plugin-no-unsanitized": "^4.1.0", "prisma": "^5.19.1" } } diff --git a/pages/api/index.ts b/pages/api/index.ts index 63468af..10fb88d 100644 --- a/pages/api/index.ts +++ b/pages/api/index.ts @@ -12,7 +12,7 @@ import fs from 'fs'; import path from 'path'; import { all } from "axios"; import { logger } from "src/helpers/common"; -import { excel } from "src/helpers/excel"; +import { ExportPublishersToExcel } from "src/helpers/excel"; /** * @@ -435,7 +435,7 @@ export default async function handler(req, res) { res.status(200).json(await dataHelper.getAllPublishersWithStatisticsMonth(day, noEndDate)); case "exportPublishersExcel": try { - await excel.ExportPublishersToExcel(req, res); + await ExportPublishersToExcel(req, res); } catch (error) { console.error(JSON.stringify(error)); } diff --git a/pages/api/shiftgenerate.ts b/pages/api/shiftgenerate.ts index 18e8495..742bb4e 100644 --- a/pages/api/shiftgenerate.ts +++ b/pages/api/shiftgenerate.ts @@ -143,7 +143,7 @@ function flattenRegistry(dayKey) { return Object.values(weekEntries).flat(); } -async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, autoFill = false, forDay, algType = 0) { +async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, autoFill = false, forDay, algType = 0, until) { let missingPublishers = []; let publishersWithChangedPref = []; @@ -176,7 +176,14 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto if (forDay) { day = monthInfo.date; - endDate.setDate(monthInfo.date.getDate() + 1); + if (until === undefined) { + const oneDayInMs = 24 * 60 * 60 * 1000; + endDate = new Date(monthInfo.date.getTime() + oneDayInMs); + } + else { + endDate = new Date(until); + } + dayNr = monthInfo.date.getDate(); weekNr = common.getWeekNumber(monthInfo.date); } @@ -184,7 +191,7 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto let publishersThisWeek = []; - + // # # # # # # # # # # # // 0. generate shifts and assign publishers from the previous month if still available while (day < endDate) { let availablePubsForTheDay = await data.filterPublishersNew('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type', day, false, false, false, true, false); @@ -262,7 +269,7 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto //ToDo: check if getAvailablePublishersForShift is working correctly. It seems not to! let availablePublishers = await getAvailablePublishersForShiftNew(shiftStart, shiftEnd, availablePubsForTheDay, publishersThisWeek); - console.log("shift " + __shiftName + " needs " + publishersNeeded + " publishers, available: " + availablePublishers.length + " for the day: " + availablePubsForTheDay.length); + console.log("shift " + __shiftName + " needs " + publishersNeeded + " publishers, available: " + availablePublishers.length + ", for the day: " + availablePubsForTheDay.length); const createdShift = await prisma.shift.create({ data: { @@ -294,21 +301,31 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto shiftEnd.setMinutes(shiftStart.getMinutes() + event.shiftDuration); } - day.setDate(day.getDate() + 1); - dayNr++; - if (common.DaysOfWeekArray[day.getDayEuropean()] === DayOfWeek.Sunday) { - weekNr++; - publishersThisWeek = []; - publishers.forEach(p => p.currentWeekAssignments = 0); + + if (forDay) { break; } + else { + day.setDate(day.getDate() + 1); + dayNr++; + if (common.DaysOfWeekArray[day.getDayEuropean()] === DayOfWeek.Sunday) { + weekNr++; + publishersThisWeek = []; + publishers.forEach(p => p.currentWeekAssignments = 0); + } } - if (forDay) break; + } + + + let from = monthInfo.firstMonday, to = monthInfo.lastSunday; + if (forDay) { + from = day; + to = endDate; } let allShifts = await prisma.shift.findMany({ where: { startTime: { - gte: monthInfo.firstMonday, - lt: monthInfo.lastSunday, + gte: from, + lt: to, }, }, include: { @@ -320,17 +337,23 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto }, }); + let publishersToday = []; let rankedPublishers = []; + // # # # # # # # # # # # // Second pass - prioritize shifts with transport where it is needed + if (forDay) { } + else { + day = new Date(monthInfo.firstMonday); + dayNr = 1; + weekNr = 1; + } + console.log("\r\n\r\n\r\n" + "# ".repeat(50)); - console.log("Second pass - fix transports " + monthInfo.monthName + " " + monthInfo.year); + console.log("Second pass - fix transports " + day.toLocaleDateString()); - day = new Date(monthInfo.firstMonday); - dayNr = 1; - weekNr = 1; while (day < endDate) { let dayOfWeekEnum = common.getDayOfWeekNameEnEnumForDate(day); let event = events.find((event) => event.dayofweek == common.DaysOfWeekArray[day.getDayEuropean()]); @@ -371,7 +394,7 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto else if (publishersNeeded > 0) { console.log("shift " + shift.name + " requires transport (" + transportCapable.length + " transport capable)"); - let availablePubsForTheShift = await data.filterPublishersNew('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type', shift.startTime, true, false, false, true, false); + let availablePubsForTheShift = await data.filterPublishersNew('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type,familyHeadId', shift.startTime, true, false, false, true, false); let availablePublishers = availablePubsForTheShift.filter(p => { const hasTransportInAvailability = shift.transportIn && p.availabilities.some(avail => avail.isWithTransportIn); @@ -386,45 +409,35 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto } else if (algType == 1) { rankedPublishers = await RankPublishersForShiftWeighted([...availablePublishers], scheduledPubsPerDayAndWeek, day, weekNr); } - // if (rankedPublishers.length > 0) { - // const newAssignment = await prisma.assignment.create({ - // data: { - // shift: { - // connect: { - // id: shift.id, - // }, - // }, - // publisher: { - // connect: { - // id: rankedPublishers[0].id, - // }, - // }, - // isWithTransport: true, - // isConfirmed: true, - // isBySystem: false, - // }, - // }); - // shift.assignments.push(newAssignment); - // publishersToday.push(rankedPublishers[0].id); - // updateRegistry(rankedPublishers[0].id, day, weekNr); - // } AddPublisherAssignment(prisma, event, shift, availablePublishers, rankedPublishers, publishersToday, day, weekNr); } } } - day.setDate(day.getDate() + 1); + if (forDay) { break; } + else { + day.setDate(day.getDate() + 1); + } } - // Fill the rest of the shifts + + // # # # # # # # # # # # + // 3. Fill the rest of the shifts let goal = 1; while (goal <= 4) { - console.log("\r\n\r\n\r\n" + "# ".repeat(50)); - console.log("Filling shifts with " + goal + " publishers " + monthInfo.monthName + " " + monthInfo.year); - day = new Date(monthInfo.firstMonday); - dayNr = 1; - weekNr = 1; + + if (forDay) { + } + else { + day = new Date(monthInfo.firstMonday); + dayNr = 1; + weekNr = 1; + } + + console.log("\r\n\r\n" + "# ".repeat(50)); + console.log("Filling shifts with " + goal + " publishers | " + day.toLocaleDateString()); + while (day < endDate) { let dayOfWeekEnum = common.getDayOfWeekNameEnEnumForDate(day); let event = events.find((event) => event.dayofweek == common.DaysOfWeekArray[day.getDayEuropean()]); @@ -452,7 +465,7 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto console.log("Filling shift " + shift.name + " with " + goal + " publishers"); let publishersNeeded = event.numberOfPublishers - shift.assignments.length; if (publishersNeeded > 0 && shift.assignments.length < goal) { - let availablePubsForTheShift = await data.filterPublishersNew('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type', shift.startTime, true, false, false, true, false); + let availablePubsForTheShift = await data.filterPublishersNew('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type,familyHeadId', shift.startTime, true, false, false, true, false); let availablePublishers = await FilterInappropriatePublishers([...availablePubsForTheShift], publishersToday, shift); if (algType == 0) { @@ -461,12 +474,17 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto rankedPublishers = await RankPublishersForShiftWeighted([...availablePublishers], scheduledPubsPerDayAndWeek, day, weekNr); } - AddPublisherAssignment(prisma, event, shift, availablePublishers, rankedPublishers, publishersToday, day, weekNr); + await AddPublisherAssignment(prisma, event, shift, availablePublishers, rankedPublishers, publishersToday, day, weekNr); + } } } - day.setDate(day.getDate() + 1); + if (forDay) { break; } + else { + day.setDate(day.getDate() + 1); + } + } goal += 1; } @@ -486,14 +504,18 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto async function AddPublisherAssignment(prisma, event, shift, availablePubsForTheShift, rankedPublishers, publishersToday, day, weekNr) { if (rankedPublishers.length == 0) { - console.log("No available publishers for shift " + shift.name); + console.log("! ! ! No available publishers for shift " + shift.name + " ! ! !"); } else { for (let i = 0; i < rankedPublishers.length; i++) { let mainPublisher = rankedPublishers[i]; - let familyMembers = availablePubsForTheShift.filter(p => (p.familyHeadId && p.familyHeadId === mainPublisher.familyHeadId) || (p.familyHeadId === mainPublisher.id)); + let familyMembers = availablePubsForTheShift.filter(p => (p.id !== mainPublisher.id && (p.id === mainPublisher.familyHeadId) || (p.familyHeadId === mainPublisher.id))); if (familyMembers.length > 0 && (shift.assignments.length + familyMembers.length + 1) <= event.numberOfPublishers) { - console.log("Assigning " + mainPublisher.firstName + " " + mainPublisher.lastName + " and family members to " + new Date(shift.startTime).getDate() + " " + shift.name); + console.log("Assigning " + mainPublisher.firstName + " " + mainPublisher.lastName + " and " + familyMembers.length + " available family members to " + new Date(shift.startTime).getDate() + " " + shift.name); + + const hasTransportInAvailability = shift.transportIn && mainPublisher.availabilities.some(avail => avail.isWithTransportIn); + const hasTransportOutAvailability = shift.transportOut && mainPublisher.availabilities.some(avail => avail.isWithTransportOut); + const newAssignment = await prisma.assignment.create({ data: { shift: { @@ -508,7 +530,7 @@ async function AddPublisherAssignment(prisma, event, shift, availablePubsForTheS }, isConfirmed: false, isBySystem: false, - isWithTransport: shift.requiresTransport, + isWithTransport: (hasTransportInAvailability || hasTransportOutAvailability), }, }); shift.assignments.push(newAssignment); @@ -540,6 +562,10 @@ async function AddPublisherAssignment(prisma, event, shift, availablePubsForTheS break; } else if (familyMembers.length == 0) { console.log("Assigning " + mainPublisher.firstName + " " + mainPublisher.lastName + " to " + new Date(shift.startTime).getDate() + " " + shift.name); + + const hasTransportInAvailability = shift.transportIn && mainPublisher.availabilities.some(avail => avail.isWithTransportIn); + const hasTransportOutAvailability = shift.transportOut && mainPublisher.availabilities.some(avail => avail.isWithTransportOut); + const newAssignment = await prisma.assignment.create({ data: { shift: { @@ -554,7 +580,7 @@ async function AddPublisherAssignment(prisma, event, shift, availablePubsForTheS }, isConfirmed: false, isBySystem: false, - isWithTransport: shift.requiresTransport, + isWithTransport: (hasTransportInAvailability || hasTransportOutAvailability), }, }); shift.assignments.push(newAssignment); @@ -564,17 +590,16 @@ async function AddPublisherAssignment(prisma, event, shift, availablePubsForTheS } } } - } -async function FilterInappropriatePublishers(availablePublishers, pubsToExclude, shift) { +async function FilterInappropriatePublishers(availablePublishers, pubsToExclude, shift, maxShifts = 0) { //ToDo: Optimization: store number of publishers, so we process the shifts from least to most available publishers later. let goodPublishers = availablePublishers.filter(p => { const isNotAssigned = !shift.assignments.some(a => a.publisher?.id === p.id); const isNotAssignedToday = !pubsToExclude.includes(p.id); const isAssignedEnough = p.currentMonthAssignments >= p.desiredShiftsPerMonth - || p.currentMonthAssignments >= 6; // overwrite the desiredShiftsPerMonth to max 6 shifts per month - return isNotAssigned && isNotAssignedToday && !isAssignedEnough; + || p.currentMonthAssignments >= maxShifts; // overwrite the desiredShiftsPerMonth to max 10 shifts per month + return isNotAssigned && isNotAssignedToday && (!isAssignedEnough || maxShifts == 0); }); return goodPublishers; } @@ -696,10 +721,17 @@ async function RankPublishersForShiftWeighted(publishers, scheduledPubsPerDayAnd const result = calculateScoreAndPenalties(p); p.score = result.score; p.penalties = result.penalties; + + p.finalScore = p.score; + if (p.finalScore > 0) { + p.penalties.forEach(penalty => { + p.finalScore *= penalty.penalty; + }); + } }); // Sort publishers based on score - let ranked = publishers.sort((a, b) => b.score - a.score); + let ranked = publishers.sort((a, b) => b.finalScore - a.finalScore); // Log the scores and penalties of the top publisher if (ranked.length > 0) { diff --git a/pages/cart/calendar/index.tsx b/pages/cart/calendar/index.tsx index 4d74ca1..b0d2df0 100644 --- a/pages/cart/calendar/index.tsx +++ b/pages/cart/calendar/index.tsx @@ -625,7 +625,7 @@ export default function CalendarPage({ initialEvents, initialShifts }) { async function setAvailabilityBlockDate(AvailabilityBlockDate: Date): Promise { // set AvailabilityBlockDate to the selected date let monthInfo = common.getMonthInfo(value); - await axiosInstance.put(`/api/?action=settings&key=AvailabilityBlockDate&value=${common.getISODateOnly(monthInfo.lastSunday)}`) + await axiosInstance.put(`/api/?action=settings&key=AvailabilityBlockDate&value=${common.getISODateOnly(value)}`) .then((response) => { console.log("AvailabilityBlockDate set to:", response.data); // setShifts([...shifts, response.data]); @@ -703,9 +703,11 @@ export default function CalendarPage({ initialEvents, initialShifts }) { - + {/* */} - + )} diff --git a/pages/dash.tsx b/pages/dash.tsx index 8128311..9e87dcf 100644 --- a/pages/dash.tsx +++ b/pages/dash.tsx @@ -219,7 +219,7 @@ export default function DashboardPage({ initialItems, initialUserId, cartEvents,

Графика на {userName}

- +
@@ -318,7 +318,7 @@ export const getServerSideProps = async (context) => { if (blockedDate) { blockedDate.value = new Date(blockedDate.value); - lastPublishedDate = lastPublishedDate > blockedDate.value ? lastPublishedDate : blockedDate.value; + lastPublishedDate = blockedDate.value; } let messages = await prisma.message.findMany({ @@ -333,8 +333,9 @@ export const getServerSideProps = async (context) => { }); messages = messages.filter((message) => { - return (!message.Survey.publicFrom || message.Survey.publicFrom >= common.getStartOfDay(new Date())) - && (!message.Survey.publicUntil || message.Survey.publicUntil <= common.getEndOfDay(new Date())) + let now = new Date(); + return (!message.Survey.publicFrom || message.Survey.publicFrom <= common.getStartOfDay(now)) + && (!message.Survey.publicUntil || message.Survey.publicUntil >= common.getEndOfDay(now)) }); messages = common.convertDatesToISOStrings(messages); messages = messages.map(message => { diff --git a/pages/permits.tsx b/pages/permits.tsx index 82bcdf1..da93484 100644 --- a/pages/permits.tsx +++ b/pages/permits.tsx @@ -49,7 +49,7 @@ const PDFViewerPage = ({ pdfFiles }) => { return (

Разрешителни

- +

За да качите файл кликнете на бутона по-долу и изберете файл от вашия компютър.

diff --git a/public/content/permits/9- Разрешително за Септември 24г..pdf b/public/content/permits/9- Разрешително за Септември 24г..pdf new file mode 100644 index 0000000..bdfcfa9 Binary files /dev/null and b/public/content/permits/9- Разрешително за Септември 24г..pdf differ diff --git a/src/helpers/calendar.js b/src/helpers/calendar.js index 4d4541a..b990f99 100644 --- a/src/helpers/calendar.js +++ b/src/helpers/calendar.js @@ -17,7 +17,7 @@ const CREDENTIALS_PATH = path.join( ); //generates iCalendar file for a single shift -GenerateICS = function (shifts) { +const GenerateICS = function (shifts) { // https://stackoverflow.com/questions/3665115/create-a-file-in-memory-for-user-to-download-not-through-server var content = "BEGIN:VCALENDAR\n"; @@ -174,76 +174,76 @@ GenerateICS = function (shifts) { // const TOKEN_PATH = path.join(process.cwd(), 'content/token.json'); // const CREDENTIALS_PATH = path.join(process.cwd(), 'content/client_secret_926212607479-d3m8hm8f8esp3rf1639prskn445sa01v.apps.googleusercontent.com.json'); -createEvent = async function createEvent(id) { - // var eventTest2 = { - // 'summary': 'Google I/O 2015', - // 'location': '800 Howard St., San Francisco, CA 94103', - // 'description': 'A chance to hear more about Google\'s developer products.', - // 'start': { - // 'dateTime': '2015-05-28T09:00:00-07:00', - // 'timeZone': 'America/Los_Angeles', - // }, - // 'end': { - // 'dateTime': '2015-05-28T17:00:00-07:00', - // 'timeZone': 'America/Los_Angeles', - // }, - // 'recurrence': [ - // 'RRULE:FREQ=DAILY;COUNT=2' - // ], - // 'attendees': [ - // { 'email': '' }, +// const createEvent = async function createEvent(id) { +// // var eventTest2 = { +// // 'summary': 'Google I/O 2015', +// // 'location': '800 Howard St., San Francisco, CA 94103', +// // 'description': 'A chance to hear more about Google\'s developer products.', +// // 'start': { +// // 'dateTime': '2015-05-28T09:00:00-07:00', +// // 'timeZone': 'America/Los_Angeles', +// // }, +// // 'end': { +// // 'dateTime': '2015-05-28T17:00:00-07:00', +// // 'timeZone': 'America/Los_Angeles', +// // }, +// // 'recurrence': [ +// // 'RRULE:FREQ=DAILY;COUNT=2' +// // ], +// // 'attendees': [ +// // { 'email': '' }, - // ], - // 'reminders': { - // 'useDefault': false, - // 'overrides': [ - // { 'method': 'email', 'minutes': 24 * 60 }, - // { 'method': 'popup', 'minutes': 10 }, - // ], - // }, - // }; - // var errors; - // var auth = await exports.authorize().then((auth) => { +// // ], +// // 'reminders': { +// // 'useDefault': false, +// // 'overrides': [ +// // { 'method': 'email', 'minutes': 24 * 60 }, +// // { 'method': 'popup', 'minutes': 10 }, +// // ], +// // }, +// // }; +// // var errors; +// // var auth = await exports.authorize().then((auth) => { - // const calendar = google.calendar({ version: 'v3', auth }); - // const res = calendar.events.insert({ - // calendarId: 'primary', - // resource: eventTest, +// // const calendar = google.calendar({ version: 'v3', auth }); +// // const res = calendar.events.insert({ +// // calendarId: 'primary', +// // resource: eventTest, - // }, (err, event) => { - // if (err) { - // console.log(`There was an error creating the event: ${err}`); - // return; - // } - // console.log(`Event created: ${event.data.htmlLink}`); - // }); - // }).catch(console.error).then((err) => { - // errors = err; - // }); - // return errors; - // } +// // }, (err, event) => { +// // if (err) { +// // console.log(`There was an error creating the event: ${err}`); +// // return; +// // } +// // console.log(`Event created: ${event.data.htmlLink}`); +// // }); +// // }).catch(console.error).then((err) => { +// // errors = err; +// // }); +// // return errors; +// // } - // authorizeNew = async function authorizeNew() { - // let client = await loadSavedCredentialsIfExist(); - // if (client) { - // return client; - // } - // // Set up the Google Calendar API client - // const calendar = google.calendar({ version: 'v3', auth }); +// // authorizeNew = async function authorizeNew() { +// // let client = await loadSavedCredentialsIfExist(); +// // if (client) { +// // return client; +// // } +// // // Set up the Google Calendar API client +// // const calendar = google.calendar({ version: 'v3', auth }); - // // Load the client secrets from a JSON file +// // // Load the client secrets from a JSON file - fs.readFile("./path/to/client_secret.json", (err, content) => { - if (err) return console.error("Error loading client secret file:", err); +// fs.readFile("./path/to/client_secret.json", (err, content) => { +// if (err) return console.error("Error loading client secret file:", err); - // Authorize a client with the loaded credentials - authorizeOA(JSON.parse(content), calendar.calendarList.list); - }); - if (client.credentials) { - await saveCredentials(client); - } - return client; -}; +// // Authorize a client with the loaded credentials +// authorizeOA(JSON.parse(content), calendar.calendarList.list); +// }); +// if (client.credentials) { +// await saveCredentials(client); +// } +// return client; +// }; // var googletoken = axiosInstance.get("/content/google_token.json"); // console.log("googletoken: " + googletoken); @@ -372,7 +372,7 @@ async function importModules() { }; } -createEvent = async (event) => { +const createEvent = async (event) => { const { open, getPort } = await importModules(); @@ -474,7 +474,7 @@ createEvent = async (event) => { } }; -SaveEventsInGoogleCalendar = async function SaveEventsInGoogleCalendar(events) { +const SaveEventsInGoogleCalendar = async function SaveEventsInGoogleCalendar(events) { // Load client secrets from a local file. try { const content = await fs.readFile(CREDENTIALS_PATH); diff --git a/src/helpers/email.js b/src/helpers/email.js index 1ae49ce..47afdad 100644 --- a/src/helpers/email.js +++ b/src/helpers/email.js @@ -5,7 +5,7 @@ const path = require('path'); const { MailtrapClient } = require("mailtrap"); const nodemailer = require("nodemailer"); const CON = require("./const"); -const CAL = require("./calendar"); +const { GenerateICS } = require("./calendar"); const common = require("./common"); const Handlebars = require('handlebars');