feat: vylepšení objednávek
CI / Generate TypeScript types (pull_request) Successful in 20s
CI / Server unit tests (pull_request) Failing after 20s
CI / Build client (pull_request) Failing after 30s
CI / Build server (pull_request) Successful in 3m13s
CI / Playwright E2E tests (pull_request) Has been skipped
CI / Build and push Docker image (pull_request) Has been skipped
CI / Notify (pull_request) Has been skipped
CI / Build client (push) Failing after 10m5s
CI / Generate TypeScript types (push) Successful in 10s
CI / Server unit tests (push) Failing after 22s
CI / Build server (push) Successful in 41s
CI / Playwright E2E tests (push) Has been skipped
CI / Build and push Docker image (push) Has been skipped
CI / Notify (push) Successful in 4s
CI / Generate TypeScript types (pull_request) Successful in 20s
CI / Server unit tests (pull_request) Failing after 20s
CI / Build client (pull_request) Failing after 30s
CI / Build server (pull_request) Successful in 3m13s
CI / Playwright E2E tests (pull_request) Has been skipped
CI / Build and push Docker image (pull_request) Has been skipped
CI / Notify (pull_request) Has been skipped
CI / Build client (push) Failing after 10m5s
CI / Generate TypeScript types (push) Successful in 10s
CI / Server unit tests (push) Failing after 22s
CI / Build server (push) Successful in 41s
CI / Playwright E2E tests (push) Has been skipped
CI / Build and push Docker image (push) Has been skipped
CI / Notify (push) Successful in 4s
This commit is contained in:
+13
-2
@@ -1,6 +1,6 @@
|
|||||||
import React, { useContext, useEffect, useMemo, useRef, useState, useCallback } from 'react';
|
import React, { useContext, useEffect, useMemo, useRef, useState, useCallback } from 'react';
|
||||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
import { EVENT_DISCONNECT, EVENT_MESSAGE, SocketContext } from './context/socket';
|
import { EVENT_DISCONNECT, EVENT_MESSAGE, EVENT_PENDING_QR, SocketContext } from './context/socket';
|
||||||
import { useAuth } from './context/auth';
|
import { useAuth } from './context/auth';
|
||||||
import Login from './Login';
|
import Login from './Login';
|
||||||
import { Alert, Button, Col, Form, Row, Table } from 'react-bootstrap';
|
import { Alert, Button, Col, Form, Row, Table } from 'react-bootstrap';
|
||||||
@@ -19,7 +19,7 @@ import { getHumanDateTime, isInTheFuture, formatDateString } from './Utils';
|
|||||||
import NoteModal from './components/modals/NoteModal';
|
import NoteModal from './components/modals/NoteModal';
|
||||||
import PayForAllModal from './components/modals/PayForAllModal';
|
import PayForAllModal from './components/modals/PayForAllModal';
|
||||||
import { useEasterEgg } from './context/eggs';
|
import { useEasterEgg } from './context/eggs';
|
||||||
import { ClientData, Food, MealSlot, PizzaOrder, DepartureTime, PizzaDayState, Restaurant, RestaurantDayMenu, RestaurantDayMenuMap, LunchChoice, LocationLunchChoicesMap, UserLunchChoice, PizzaVariant, getData, getEasterEggImage, addPizza, removePizza, updatePizzaDayNote, createPizzaDay, deletePizzaDay, lockPizzaDay, unlockPizzaDay, finishOrder, finishDelivery, addChoice, jdemeObed, removeChoices, removeChoice, updateNote, changeDepartureTime, setBuyer, dismissQr, generateQr } from '../../types';
|
import { ClientData, Food, MealSlot, PendingQr, PizzaOrder, DepartureTime, PizzaDayState, Restaurant, RestaurantDayMenu, RestaurantDayMenuMap, LunchChoice, LocationLunchChoicesMap, UserLunchChoice, PizzaVariant, getData, getEasterEggImage, addPizza, removePizza, updatePizzaDayNote, createPizzaDay, deletePizzaDay, lockPizzaDay, unlockPizzaDay, finishOrder, finishDelivery, addChoice, jdemeObed, removeChoices, removeChoice, updateNote, changeDepartureTime, setBuyer, dismissQr, generateQr } from '../../types';
|
||||||
import { getLunchChoiceName } from './enums';
|
import { getLunchChoiceName } from './enums';
|
||||||
// import FallingLeaves, { LEAF_PRESETS, LEAF_COLOR_THEMES } from './FallingLeaves';
|
// import FallingLeaves, { LEAF_PRESETS, LEAF_COLOR_THEMES } from './FallingLeaves';
|
||||||
// import './FallingLeaves.scss';
|
// import './FallingLeaves.scss';
|
||||||
@@ -132,14 +132,25 @@ function App() {
|
|||||||
setData(newData);
|
setData(newData);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
socket.on(EVENT_PENDING_QR, (pendingQr: PendingQr) => {
|
||||||
|
setData(prev => prev ? { ...prev, pendingQrs: [...(prev.pendingQrs ?? []), pendingQr] } : prev);
|
||||||
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
socket.off(EVENT_CONNECT);
|
socket.off(EVENT_CONNECT);
|
||||||
socket.off(EVENT_DISCONNECT);
|
socket.off(EVENT_DISCONNECT);
|
||||||
socket.off(EVENT_MESSAGE);
|
socket.off(EVENT_MESSAGE);
|
||||||
|
socket.off(EVENT_PENDING_QR);
|
||||||
}
|
}
|
||||||
}, [socket]);
|
}, [socket]);
|
||||||
|
|
||||||
|
// Připojení do osobní socket místnosti po přihlášení
|
||||||
|
useEffect(() => {
|
||||||
|
if (auth?.login) {
|
||||||
|
socket.emit('join', auth.login);
|
||||||
|
}
|
||||||
|
}, [auth?.login, socket]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!auth?.login || !data?.choices) {
|
if (!auth?.login || !data?.choices) {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -0,0 +1,192 @@
|
|||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { Modal, Button, Form, Table, Alert } from "react-bootstrap";
|
||||||
|
import { updateGroupFees, OrderGroup, OrderGroupMember } from "../../../../types";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
isOpen: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
group: OrderGroup;
|
||||||
|
onSaved: (data: any) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
function parseNum(s: string): number {
|
||||||
|
const n = parseFloat(s.replace(',', '.'));
|
||||||
|
return isNaN(n) || n < 0 ? 0 : Math.round(n * 100) / 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeMemberTotal(member: OrderGroupMember, feeShare: number, discountType: string, discountValue: number, memberCount: number): number {
|
||||||
|
const base = member.amount ?? 0;
|
||||||
|
const surcharge = member.surchargeAmount ?? 0;
|
||||||
|
const discount = discountType === 'percent'
|
||||||
|
? Math.round((base + surcharge) * discountValue / 100 * 100) / 100
|
||||||
|
: Math.round(discountValue / memberCount * 100) / 100;
|
||||||
|
return Math.round((base + surcharge + feeShare - discount) * 100) / 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function EditGroupFeesModal({ isOpen, onClose, group, onSaved }: Readonly<Props>) {
|
||||||
|
const [fees, setFees] = useState('');
|
||||||
|
const [shipping, setShipping] = useState('');
|
||||||
|
const [tip, setTip] = useState('');
|
||||||
|
const [discountType, setDiscountType] = useState<'percent' | 'fixed'>('percent');
|
||||||
|
const [discountValue, setDiscountValue] = useState('');
|
||||||
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isOpen) return;
|
||||||
|
setFees(group.fees ? String(group.fees) : '');
|
||||||
|
setShipping(group.shipping ? String(group.shipping) : '');
|
||||||
|
setTip(group.tip ? String(group.tip) : '');
|
||||||
|
setDiscountType((group.discountType as 'percent' | 'fixed') ?? 'percent');
|
||||||
|
setDiscountValue(group.discountValue ? String(group.discountValue) : '');
|
||||||
|
setError(null);
|
||||||
|
}, [isOpen, group]);
|
||||||
|
|
||||||
|
const memberEntries = Object.entries(group.members) as [string, OrderGroupMember][];
|
||||||
|
const memberCount = memberEntries.length;
|
||||||
|
|
||||||
|
const feesNum = parseNum(fees);
|
||||||
|
const shippingNum = parseNum(shipping);
|
||||||
|
const tipNum = parseNum(tip);
|
||||||
|
const discountNum = parseNum(discountValue);
|
||||||
|
const totalFees = feesNum + shippingNum + tipNum;
|
||||||
|
const feeShare = memberCount > 0 ? Math.round(totalFees / memberCount * 100) / 100 : 0;
|
||||||
|
|
||||||
|
const handleSave = async () => {
|
||||||
|
setError(null);
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
const body: Record<string, any> = { id: group.id };
|
||||||
|
body.fees = feesNum;
|
||||||
|
body.shipping = shippingNum;
|
||||||
|
body.tip = tipNum;
|
||||||
|
if (discountNum > 0) {
|
||||||
|
body.discountType = discountType;
|
||||||
|
body.discountValue = discountNum;
|
||||||
|
} else {
|
||||||
|
body.discountType = '';
|
||||||
|
body.discountValue = 0;
|
||||||
|
}
|
||||||
|
const res = await updateGroupFees({ body });
|
||||||
|
if (res.error) {
|
||||||
|
setError((res.error as any).error || 'Nastala chyba');
|
||||||
|
} else {
|
||||||
|
onSaved(res.data);
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
} catch (e: any) {
|
||||||
|
setError(e.message || 'Nastala chyba');
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal show={isOpen} onHide={onClose} size="lg">
|
||||||
|
<Modal.Header closeButton>
|
||||||
|
<Modal.Title><h2>Poplatky skupiny — {group.name}</h2></Modal.Title>
|
||||||
|
</Modal.Header>
|
||||||
|
<Modal.Body>
|
||||||
|
{error && (
|
||||||
|
<Alert variant="danger" onClose={() => setError(null)} dismissible>{error}</Alert>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="d-flex gap-3 flex-wrap mb-3">
|
||||||
|
<Form.Group>
|
||||||
|
<Form.Label>Poplatky (Kč)</Form.Label>
|
||||||
|
<Form.Control
|
||||||
|
type="number" min={0} step={0.01}
|
||||||
|
value={fees} onChange={e => setFees(e.target.value)}
|
||||||
|
placeholder="0" style={{ width: 110 }}
|
||||||
|
onKeyDown={e => e.stopPropagation()}
|
||||||
|
/>
|
||||||
|
</Form.Group>
|
||||||
|
<Form.Group>
|
||||||
|
<Form.Label>Doprava (Kč)</Form.Label>
|
||||||
|
<Form.Control
|
||||||
|
type="number" min={0} step={0.01}
|
||||||
|
value={shipping} onChange={e => setShipping(e.target.value)}
|
||||||
|
placeholder="0" style={{ width: 110 }}
|
||||||
|
onKeyDown={e => e.stopPropagation()}
|
||||||
|
/>
|
||||||
|
</Form.Group>
|
||||||
|
<Form.Group>
|
||||||
|
<Form.Label>Spropitné (Kč)</Form.Label>
|
||||||
|
<Form.Control
|
||||||
|
type="number" min={0} step={0.01}
|
||||||
|
value={tip} onChange={e => setTip(e.target.value)}
|
||||||
|
placeholder="0" style={{ width: 110 }}
|
||||||
|
onKeyDown={e => e.stopPropagation()}
|
||||||
|
/>
|
||||||
|
</Form.Group>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="d-flex gap-3 align-items-end flex-wrap mb-3">
|
||||||
|
<Form.Group>
|
||||||
|
<Form.Label>Sleva</Form.Label>
|
||||||
|
<div className="d-flex gap-2 align-items-center">
|
||||||
|
<Form.Select
|
||||||
|
value={discountType}
|
||||||
|
onChange={e => setDiscountType(e.target.value as 'percent' | 'fixed')}
|
||||||
|
style={{ width: 160 }}
|
||||||
|
>
|
||||||
|
<option value="percent">Procentuální (%)</option>
|
||||||
|
<option value="fixed">Pevná částka (Kč)</option>
|
||||||
|
</Form.Select>
|
||||||
|
<Form.Control
|
||||||
|
type="number" min={0} step={discountType === 'percent' ? 1 : 0.01}
|
||||||
|
value={discountValue} onChange={e => setDiscountValue(e.target.value)}
|
||||||
|
placeholder="0" style={{ width: 100 }}
|
||||||
|
onKeyDown={e => e.stopPropagation()}
|
||||||
|
/>
|
||||||
|
<span className="text-muted">{discountType === 'percent' ? '%' : 'Kč'}</span>
|
||||||
|
</div>
|
||||||
|
</Form.Group>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<h6>Náhled celkových částek ({memberCount} členů, {feeShare > 0 ? `poplatek ${feeShare} Kč/os.` : 'bez poplatku'})</h6>
|
||||||
|
<Table size="sm" bordered>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Člen</th>
|
||||||
|
<th className="text-end">Základ</th>
|
||||||
|
<th className="text-end">Příplatek</th>
|
||||||
|
<th className="text-end">Poplatek</th>
|
||||||
|
<th className="text-end">Sleva</th>
|
||||||
|
<th className="text-end fw-bold">Celkem</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{memberEntries.map(([login, member]) => {
|
||||||
|
const base = member.amount ?? 0;
|
||||||
|
const surcharge = member.surchargeAmount ?? 0;
|
||||||
|
const discount = discountNum > 0
|
||||||
|
? (discountType === 'percent'
|
||||||
|
? Math.round((base + surcharge) * discountNum / 100 * 100) / 100
|
||||||
|
: Math.round(discountNum / memberCount * 100) / 100)
|
||||||
|
: 0;
|
||||||
|
const total = computeMemberTotal(member, feeShare, discountType, discountNum, memberCount);
|
||||||
|
return (
|
||||||
|
<tr key={login}>
|
||||||
|
<td><strong>{login}</strong></td>
|
||||||
|
<td className="text-end">{base > 0 ? `${base} Kč` : '—'}</td>
|
||||||
|
<td className="text-end">{surcharge > 0 ? `${surcharge} Kč` : '—'}</td>
|
||||||
|
<td className="text-end">{feeShare > 0 ? `${feeShare} Kč` : '—'}</td>
|
||||||
|
<td className="text-end text-danger">{discount > 0 ? `-${discount} Kč` : '—'}</td>
|
||||||
|
<td className="text-end fw-bold">{total > 0 ? `${total} Kč` : '—'}</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</tbody>
|
||||||
|
</Table>
|
||||||
|
</Modal.Body>
|
||||||
|
<Modal.Footer>
|
||||||
|
<Button variant="secondary" onClick={onClose} disabled={loading}>Storno</Button>
|
||||||
|
<Button variant="primary" onClick={handleSave} disabled={loading}>
|
||||||
|
{loading ? 'Ukládám...' : 'Uložit'}
|
||||||
|
</Button>
|
||||||
|
</Modal.Footer>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,15 +1,7 @@
|
|||||||
import { useState, useEffect, useCallback } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { Modal, Button, Form, Table, Alert } from "react-bootstrap";
|
import { Modal, Button, Form, Table, Alert } from "react-bootstrap";
|
||||||
import { generateQr, OrderGroup, OrderGroupMember, QrRecipient } from "../../../../types";
|
import { generateQr, OrderGroup, OrderGroupMember, QrRecipient } from "../../../../types";
|
||||||
|
|
||||||
type DinerEntry = {
|
|
||||||
login: string;
|
|
||||||
baseAmount: number;
|
|
||||||
surchargeText: string;
|
|
||||||
surchargeAmount: string;
|
|
||||||
included: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
@@ -20,22 +12,14 @@ type Props = {
|
|||||||
groupId?: string;
|
groupId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
function sanitizeAmount(value: string): string {
|
type DinerEntry = {
|
||||||
return value.replace(/[^0-9.,]/g, '').replace(',', '.');
|
login: string;
|
||||||
}
|
member: OrderGroupMember;
|
||||||
|
included: boolean;
|
||||||
function parseAmount(s: string): number | null {
|
};
|
||||||
if (!s || s.trim().length === 0) return null;
|
|
||||||
const n = parseFloat(s);
|
|
||||||
if (isNaN(n) || n < 0) return null;
|
|
||||||
const parts = s.split('.');
|
|
||||||
if (parts.length === 2 && parts[1].length > 2) return null;
|
|
||||||
return Math.round(n * 100) / 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function PayForGroupModal({ isOpen, onClose, group, payerLogin, bankAccount, bankAccountHolder, groupId }: Readonly<Props>) {
|
export default function PayForGroupModal({ isOpen, onClose, group, payerLogin, bankAccount, bankAccountHolder, groupId }: Readonly<Props>) {
|
||||||
const [diners, setDiners] = useState<DinerEntry[]>([]);
|
const [diners, setDiners] = useState<DinerEntry[]>([]);
|
||||||
const [tipTotal, setTipTotal] = useState('');
|
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [success, setSuccess] = useState(false);
|
const [success, setSuccess] = useState(false);
|
||||||
@@ -44,49 +28,39 @@ export default function PayForGroupModal({ isOpen, onClose, group, payerLogin, b
|
|||||||
if (!isOpen) return;
|
if (!isOpen) return;
|
||||||
const entries: DinerEntry[] = (Object.entries(group.members) as [string, OrderGroupMember][]).map(([login, member]) => ({
|
const entries: DinerEntry[] = (Object.entries(group.members) as [string, OrderGroupMember][]).map(([login, member]) => ({
|
||||||
login,
|
login,
|
||||||
baseAmount: member.amount ?? 0,
|
member,
|
||||||
surchargeText: member.surchargeText ?? '',
|
|
||||||
surchargeAmount: member.surchargeAmount != null ? String(member.surchargeAmount) : '',
|
|
||||||
included: login !== payerLogin,
|
included: login !== payerLogin,
|
||||||
}));
|
}));
|
||||||
setDiners(entries);
|
setDiners(entries);
|
||||||
setTipTotal('');
|
|
||||||
setError(null);
|
setError(null);
|
||||||
setSuccess(false);
|
setSuccess(false);
|
||||||
}, [isOpen, group, payerLogin]);
|
}, [isOpen, group, payerLogin]);
|
||||||
|
|
||||||
const includedNonPayers = diners.filter(d => d.included && d.login !== payerLogin);
|
const memberCount = diners.length;
|
||||||
|
const fees = group.fees ?? 0;
|
||||||
|
const shipping = group.shipping ?? 0;
|
||||||
|
const tip = group.tip ?? 0;
|
||||||
|
const totalFees = fees + shipping + tip;
|
||||||
|
const feeShare = memberCount > 0 ? Math.round(totalFees / memberCount * 100) / 100 : 0;
|
||||||
|
|
||||||
const tipPerPerson = (() => {
|
const getMemberTotal = (entry: DinerEntry): number => {
|
||||||
if (includedNonPayers.length === 0) return 0;
|
const base = entry.member.amount ?? 0;
|
||||||
const tip = parseAmount(tipTotal);
|
const surcharge = entry.member.surchargeAmount ?? 0;
|
||||||
if (tip === null || tip === 0) return 0;
|
const discountType = group.discountType;
|
||||||
const totalPeople = includedNonPayers.length + 1; // +1 for payer
|
const discountValue = group.discountValue ?? 0;
|
||||||
return Math.round((tip / totalPeople) * 100) / 100;
|
const discount = discountValue > 0
|
||||||
})();
|
? (discountType === 'percent'
|
||||||
const payerTipShare = (() => {
|
? Math.round((base + surcharge) * discountValue / 100 * 100) / 100
|
||||||
const tip = parseAmount(tipTotal);
|
: Math.round(discountValue / memberCount * 100) / 100)
|
||||||
if (!tip) return 0;
|
: 0;
|
||||||
return Math.round((tip - tipPerPerson * includedNonPayers.length) * 100) / 100;
|
return Math.round((base + surcharge + feeShare - discount) * 100) / 100;
|
||||||
})();
|
|
||||||
|
|
||||||
const getTotal = (d: DinerEntry): number => {
|
|
||||||
const surcharge = parseAmount(d.surchargeAmount) ?? 0;
|
|
||||||
const tip = d.login === payerLogin ? payerTipShare : tipPerPerson;
|
|
||||||
return Math.round((d.baseAmount + surcharge + tip) * 100) / 100;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleInclude = useCallback((login: string, checked: boolean) => {
|
const includedNonPayers = diners.filter(d => d.included && d.login !== payerLogin);
|
||||||
|
|
||||||
|
const handleInclude = (login: string, checked: boolean) => {
|
||||||
setDiners(prev => prev.map(d => d.login === login ? { ...d, included: checked } : d));
|
setDiners(prev => prev.map(d => d.login === login ? { ...d, included: checked } : d));
|
||||||
}, []);
|
};
|
||||||
|
|
||||||
const handleSurchargeText = useCallback((login: string, value: string) => {
|
|
||||||
setDiners(prev => prev.map(d => d.login === login ? { ...d, surchargeText: value } : d));
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleSurchargeAmount = useCallback((login: string, value: string) => {
|
|
||||||
setDiners(prev => prev.map(d => d.login === login ? { ...d, surchargeAmount: sanitizeAmount(value) } : d));
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleGenerate = async () => {
|
const handleGenerate = async () => {
|
||||||
setError(null);
|
setError(null);
|
||||||
@@ -94,7 +68,7 @@ export default function PayForGroupModal({ isOpen, onClose, group, payerLogin, b
|
|||||||
|
|
||||||
for (const d of diners) {
|
for (const d of diners) {
|
||||||
if (!d.included || d.login === payerLogin) continue;
|
if (!d.included || d.login === payerLogin) continue;
|
||||||
const total = getTotal(d);
|
const total = getMemberTotal(d);
|
||||||
if (total <= 0) {
|
if (total <= 0) {
|
||||||
setError(`Celková částka pro ${d.login} musí být kladná`);
|
setError(`Celková částka pro ${d.login} musí být kladná`);
|
||||||
return;
|
return;
|
||||||
@@ -134,10 +108,12 @@ export default function PayForGroupModal({ isOpen, onClose, group, payerLogin, b
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const hasFees = totalFees > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal show={isOpen} onHide={onClose} size="lg">
|
<Modal show={isOpen} onHide={onClose} size="lg">
|
||||||
<Modal.Header closeButton>
|
<Modal.Header closeButton>
|
||||||
<Modal.Title><h2>Zaplatit za skupinu — {group.name}</h2></Modal.Title>
|
<Modal.Title><h2>Generovat QR — {group.name}</h2></Modal.Title>
|
||||||
</Modal.Header>
|
</Modal.Header>
|
||||||
<Modal.Body>
|
<Modal.Body>
|
||||||
{success ? (
|
{success ? (
|
||||||
@@ -146,7 +122,7 @@ export default function PayForGroupModal({ isOpen, onClose, group, payerLogin, b
|
|||||||
</Alert>
|
</Alert>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<p>Zaplatili jste za skupinu. Nastavte příplatky a společné poplatky, poté vygenerujte QR kódy pro ostatní.</p>
|
<p>Zaplatili jste za skupinu. Vyberte, komu vygenerovat QR kód k úhradě.</p>
|
||||||
|
|
||||||
{error && (
|
{error && (
|
||||||
<Alert variant="danger" onClose={() => setError(null)} dismissible>
|
<Alert variant="danger" onClose={() => setError(null)} dismissible>
|
||||||
@@ -154,21 +130,36 @@ export default function PayForGroupModal({ isOpen, onClose, group, payerLogin, b
|
|||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{hasFees && (
|
||||||
|
<div className="d-flex gap-3 mb-2 text-muted" style={{ fontSize: '0.9em' }}>
|
||||||
|
{fees > 0 && <span>Poplatky: <strong>{fees} Kč</strong></span>}
|
||||||
|
{shipping > 0 && <span>Doprava: <strong>{shipping} Kč</strong></span>}
|
||||||
|
{tip > 0 && <span>Spropitné: <strong>{tip} Kč</strong></span>}
|
||||||
|
<span>→ {feeShare} Kč/os.</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{group.discountValue != null && group.discountValue > 0 && (
|
||||||
|
<div className="mb-2 text-success" style={{ fontSize: '0.9em' }}>
|
||||||
|
Sleva: {group.discountType === 'percent' ? `${group.discountValue}%` : `${group.discountValue} Kč`}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<Table striped bordered hover responsive size="sm">
|
<Table striped bordered hover responsive size="sm">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style={{ width: 40 }}></th>
|
<th style={{ width: 40 }}></th>
|
||||||
<th>Člen</th>
|
<th>Člen</th>
|
||||||
<th style={{ width: 90 }}>Základ (Kč)</th>
|
<th style={{ width: 90 }} className="text-end">Základ</th>
|
||||||
<th style={{ width: 220 }}>Příplatek</th>
|
<th style={{ width: 90 }} className="text-end">Příplatek</th>
|
||||||
<th style={{ width: 90 }}>Poplatek</th>
|
{hasFees && <th style={{ width: 90 }} className="text-end">Poplatek</th>}
|
||||||
<th style={{ width: 90 }}>Celkem</th>
|
<th style={{ width: 90 }} className="text-end fw-bold">Celkem</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{diners.map(d => {
|
{diners.map(d => {
|
||||||
const isPayer = d.login === payerLogin;
|
const isPayer = d.login === payerLogin;
|
||||||
const total = getTotal(d);
|
const total = getMemberTotal(d);
|
||||||
|
const surcharge = d.member.surchargeAmount ?? 0;
|
||||||
return (
|
return (
|
||||||
<tr key={d.login} className={!d.included && !isPayer ? 'text-muted' : ''}>
|
<tr key={d.login} className={!d.included && !isPayer ? 'text-muted' : ''}>
|
||||||
<td className="text-center">
|
<td className="text-center">
|
||||||
@@ -182,74 +173,39 @@ export default function PayForGroupModal({ isOpen, onClose, group, payerLogin, b
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
<td><strong>{d.login}</strong></td>
|
|
||||||
<td className="text-end">
|
|
||||||
{d.baseAmount > 0 ? `${d.baseAmount} Kč` : <span className="text-muted">—</span>}
|
|
||||||
</td>
|
|
||||||
<td>
|
<td>
|
||||||
<div className="d-flex gap-1">
|
<strong>{d.login}</strong>
|
||||||
<Form.Control
|
{d.member.surchargeText && (
|
||||||
type="text"
|
<small className="text-muted ms-1">({d.member.surchargeText})</small>
|
||||||
placeholder="popis"
|
)}
|
||||||
value={d.surchargeText}
|
|
||||||
onChange={e => handleSurchargeText(d.login, e.target.value)}
|
|
||||||
disabled={!isPayer && !d.included}
|
|
||||||
size="sm"
|
|
||||||
onKeyDown={e => e.stopPropagation()}
|
|
||||||
/>
|
|
||||||
<Form.Control
|
|
||||||
type="text"
|
|
||||||
placeholder="Kč"
|
|
||||||
value={d.surchargeAmount}
|
|
||||||
onChange={e => handleSurchargeAmount(d.login, e.target.value)}
|
|
||||||
disabled={!isPayer && !d.included}
|
|
||||||
size="sm"
|
|
||||||
style={{ width: 70 }}
|
|
||||||
onKeyDown={e => e.stopPropagation()}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
<td className="text-end">
|
<td className="text-end">
|
||||||
{(() => { const s = isPayer ? payerTipShare : tipPerPerson; return s > 0 ? `${s} Kč` : '—'; })()}
|
{(d.member.amount ?? 0) > 0 ? `${d.member.amount} Kč` : <span className="text-muted">—</span>}
|
||||||
</td>
|
</td>
|
||||||
|
<td className="text-end">
|
||||||
|
{surcharge > 0 ? `${surcharge} Kč` : <span className="text-muted">—</span>}
|
||||||
|
</td>
|
||||||
|
{hasFees && (
|
||||||
|
<td className="text-end">
|
||||||
|
{feeShare > 0 ? `${feeShare} Kč` : '—'}
|
||||||
|
</td>
|
||||||
|
)}
|
||||||
<td className="text-end fw-bold">
|
<td className="text-end fw-bold">
|
||||||
{`${total} Kč`}
|
{total > 0 ? `${total} Kč` : <span className="text-muted">—</span>}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</tbody>
|
</tbody>
|
||||||
</Table>
|
</Table>
|
||||||
|
|
||||||
<div className="d-flex align-items-center gap-2 mt-2">
|
|
||||||
<label className="mb-0 text-nowrap">Poplatky celkem (Kč):</label>
|
|
||||||
<Form.Control
|
|
||||||
type="text"
|
|
||||||
placeholder="0"
|
|
||||||
value={tipTotal}
|
|
||||||
onChange={e => setTipTotal(sanitizeAmount(e.target.value))}
|
|
||||||
size="sm"
|
|
||||||
style={{ width: 100 }}
|
|
||||||
onKeyDown={e => e.stopPropagation()}
|
|
||||||
/>
|
|
||||||
<small className="text-muted">
|
|
||||||
{includedNonPayers.length > 0 && tipPerPerson > 0
|
|
||||||
? `(${tipPerPerson} Kč / osoba)`
|
|
||||||
: ''}
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Modal.Body>
|
</Modal.Body>
|
||||||
<Modal.Footer>
|
<Modal.Footer>
|
||||||
{!success && (
|
{!success && (
|
||||||
<>
|
<>
|
||||||
<span className="me-auto text-muted">
|
<span className="me-auto text-muted">Příjemci: {includedNonPayers.length}</span>
|
||||||
Příjemci: {includedNonPayers.length}
|
<Button variant="secondary" onClick={onClose} disabled={loading}>Storno</Button>
|
||||||
</span>
|
|
||||||
<Button variant="secondary" onClick={onClose} disabled={loading}>
|
|
||||||
Storno
|
|
||||||
</Button>
|
|
||||||
<Button
|
<Button
|
||||||
variant="primary"
|
variant="primary"
|
||||||
onClick={handleGenerate}
|
onClick={handleGenerate}
|
||||||
|
|||||||
@@ -18,3 +18,4 @@ export const SocketContext = React.createContext();
|
|||||||
export const EVENT_CONNECT = 'connect';
|
export const EVENT_CONNECT = 'connect';
|
||||||
export const EVENT_DISCONNECT = 'disconnect';
|
export const EVENT_DISCONNECT = 'disconnect';
|
||||||
export const EVENT_MESSAGE = 'message';
|
export const EVENT_MESSAGE = 'message';
|
||||||
|
export const EVENT_PENDING_QR = 'pendingQr';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useContext, useEffect, useRef, useState } from 'react';
|
import { useContext, useEffect, useRef, useState } from 'react';
|
||||||
import { Alert, Badge, Button, Card, Form, Modal, Table } from 'react-bootstrap';
|
import { Alert, Badge, Button, Card, Form, Modal, OverlayTrigger, Table, Tooltip } from 'react-bootstrap';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { faTrashCan } from '@fortawesome/free-regular-svg-icons';
|
import { faTrashCan } from '@fortawesome/free-regular-svg-icons';
|
||||||
import { faBasketShopping, faCircleCheck, faGear, faLock, faLockOpen, faSearch, faUserPlus } from '@fortawesome/free-solid-svg-icons';
|
import { faBasketShopping, faCircleCheck, faGear, faLock, faLockOpen, faSearch, faUserPlus } from '@fortawesome/free-solid-svg-icons';
|
||||||
@@ -16,6 +16,7 @@ import Footer from '../components/Footer';
|
|||||||
import Loader from '../components/Loader';
|
import Loader from '../components/Loader';
|
||||||
import StoreAdminModal from '../components/modals/StoreAdminModal';
|
import StoreAdminModal from '../components/modals/StoreAdminModal';
|
||||||
import PayForGroupModal from '../components/modals/PayForGroupModal';
|
import PayForGroupModal from '../components/modals/PayForGroupModal';
|
||||||
|
import EditGroupFeesModal from '../components/modals/EditGroupFeesModal';
|
||||||
|
|
||||||
const SLOT = MealSlot.EXTRA;
|
const SLOT = MealSlot.EXTRA;
|
||||||
const TIME_REGEX = /^([01]\d|2[0-3]):[0-5]\d$/;
|
const TIME_REGEX = /^([01]\d|2[0-3]):[0-5]\d$/;
|
||||||
@@ -41,8 +42,10 @@ export default function OrderGroupsPage() {
|
|||||||
const [adminModalOpen, setAdminModalOpen] = useState(false);
|
const [adminModalOpen, setAdminModalOpen] = useState(false);
|
||||||
const [editAmounts, setEditAmounts] = useState<Record<string, string>>({});
|
const [editAmounts, setEditAmounts] = useState<Record<string, string>>({});
|
||||||
const [editNotes, setEditNotes] = useState<Record<string, string>>({});
|
const [editNotes, setEditNotes] = useState<Record<string, string>>({});
|
||||||
|
const [editSurcharges, setEditSurcharges] = useState<Record<string, { text: string; amount: string }>>({});
|
||||||
const [editTimes, setEditTimes] = useState<Record<string, { orderedAt: string; deliveryAt: string }>>({});
|
const [editTimes, setEditTimes] = useState<Record<string, { orderedAt: string; deliveryAt: string }>>({});
|
||||||
const [payModal, setPayModal] = useState<OrderGroup | null>(null);
|
const [payModal, setPayModal] = useState<OrderGroup | null>(null);
|
||||||
|
const [feesModal, setFeesModal] = useState<OrderGroup | null>(null);
|
||||||
const [confirmOrderGroup, setConfirmOrderGroup] = useState<OrderGroup | null>(null);
|
const [confirmOrderGroup, setConfirmOrderGroup] = useState<OrderGroup | null>(null);
|
||||||
const [pageError, setPageError] = useState<string | null>(null);
|
const [pageError, setPageError] = useState<string | null>(null);
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
@@ -133,6 +136,19 @@ export default function OrderGroupsPage() {
|
|||||||
if (ok) setEditNotes(prev => { const next = { ...prev }; delete next[key]; return next; });
|
if (ok) setEditNotes(prev => { const next = { ...prev }; delete next[key]; return next; });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSaveSurcharge = async (groupId: string, login: string) => {
|
||||||
|
const key = `${groupId}:${login}`;
|
||||||
|
const surchargeText = editSurcharges[key]?.text ?? '';
|
||||||
|
const rawAmount = editSurcharges[key]?.amount ?? '';
|
||||||
|
const surchargeAmount = rawAmount === '' ? 0 : parseFloat(rawAmount.replace(',', '.'));
|
||||||
|
if (rawAmount !== '' && (isNaN(surchargeAmount) || surchargeAmount < 0)) {
|
||||||
|
setPageError('Zadejte platnou výši příplatku');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const ok = await refresh(() => updateGroupMember({ body: { id: groupId, login, surchargeText, surchargeAmount: rawAmount === '' ? 0 : surchargeAmount } }));
|
||||||
|
if (ok) setEditSurcharges(prev => { const next = { ...prev }; delete next[key]; return next; });
|
||||||
|
};
|
||||||
|
|
||||||
const handleSaveTimes = async (group: OrderGroup) => {
|
const handleSaveTimes = async (group: OrderGroup) => {
|
||||||
const times = editTimes[group.id];
|
const times = editTimes[group.id];
|
||||||
if (!times) return;
|
if (!times) return;
|
||||||
@@ -234,8 +250,23 @@ export default function OrderGroupsPage() {
|
|||||||
const isOrdered = group.state === GroupState.ORDERED;
|
const isOrdered = group.state === GroupState.ORDERED;
|
||||||
const isLocked = group.state === GroupState.LOCKED;
|
const isLocked = group.state === GroupState.LOCKED;
|
||||||
const memberEntries = Object.entries(group.members) as [string, OrderGroupMember][];
|
const memberEntries = Object.entries(group.members) as [string, OrderGroupMember][];
|
||||||
|
const memberCount = memberEntries.length;
|
||||||
const editingTimes = group.id in editTimes;
|
const editingTimes = group.id in editTimes;
|
||||||
|
|
||||||
|
const totalFees = (group.fees ?? 0) + (group.shipping ?? 0) + (group.tip ?? 0);
|
||||||
|
const feeShare = memberCount > 0 ? Math.round(totalFees / memberCount * 100) / 100 : 0;
|
||||||
|
const getMemberTotal = (m: OrderGroupMember) => {
|
||||||
|
const base = m.amount ?? 0;
|
||||||
|
const surcharge = m.surchargeAmount ?? 0;
|
||||||
|
const dv = group.discountValue ?? 0;
|
||||||
|
const discount = dv > 0
|
||||||
|
? (group.discountType === 'percent'
|
||||||
|
? Math.round((base + surcharge) * dv / 100 * 100) / 100
|
||||||
|
: Math.round(dv / memberCount * 100) / 100)
|
||||||
|
: 0;
|
||||||
|
return Math.round((base + surcharge + feeShare - discount) * 100) / 100;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card key={group.id} className="mb-3 fade-in">
|
<Card key={group.id} className="mb-3 fade-in">
|
||||||
<Card.Header className="d-flex justify-content-between align-items-center">
|
<Card.Header className="d-flex justify-content-between align-items-center">
|
||||||
@@ -247,6 +278,9 @@ export default function OrderGroupsPage() {
|
|||||||
<div className="d-flex gap-2">
|
<div className="d-flex gap-2">
|
||||||
{isCreator && !isOrdered && (
|
{isCreator && !isOrdered && (
|
||||||
<>
|
<>
|
||||||
|
<Button variant="outline-info" size="sm" onClick={() => setFeesModal(group)} title="Upravit poplatky a slevu">
|
||||||
|
Poplatky
|
||||||
|
</Button>
|
||||||
<Button variant="outline-secondary" size="sm" onClick={() => handleToggleLock(group)} title={isLocked ? 'Odemknout' : 'Uzamknout'}>
|
<Button variant="outline-secondary" size="sm" onClick={() => handleToggleLock(group)} title={isLocked ? 'Odemknout' : 'Uzamknout'}>
|
||||||
<FontAwesomeIcon icon={isLocked ? faLockOpen : faLock} />
|
<FontAwesomeIcon icon={isLocked ? faLockOpen : faLock} />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -286,28 +320,35 @@ export default function OrderGroupsPage() {
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Člen</th>
|
<th>Člen</th>
|
||||||
<th style={{ width: 130 }}>Částka (Kč)</th>
|
<th style={{ width: 120 }}>Částka (Kč)</th>
|
||||||
|
<th style={{ width: 180 }}>Příplatek</th>
|
||||||
<th>Poznámka</th>
|
<th>Poznámka</th>
|
||||||
|
<th style={{ width: 90 }}>Celkem</th>
|
||||||
<th style={{ width: 40 }}></th>
|
<th style={{ width: 40 }}></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{memberEntries.map(([memberLogin, member]) => {
|
{memberEntries.map(([memberLogin, member]) => {
|
||||||
const amountKey = `${group.id}:${memberLogin}`;
|
const key = `${group.id}:${memberLogin}`;
|
||||||
const noteKey = `${group.id}:${memberLogin}`;
|
const editingAmount = key in editAmounts;
|
||||||
const editingAmount = amountKey in editAmounts;
|
const editingNote = key in editNotes;
|
||||||
const editingNote = noteKey in editNotes;
|
const editingSurcharge = key in editSurcharges;
|
||||||
const canEdit = canEditMember(group, memberLogin);
|
const canEdit = canEditMember(group, memberLogin);
|
||||||
|
const memberTotal = getMemberTotal(member);
|
||||||
return (
|
return (
|
||||||
<tr key={memberLogin}>
|
<tr key={memberLogin}>
|
||||||
<td>
|
<td>
|
||||||
<span className="user-info">
|
<span className="user-info">
|
||||||
<strong>{memberLogin}</strong>
|
<strong>{memberLogin}</strong>
|
||||||
{memberLogin === group.creatorLogin && (
|
{memberLogin === group.creatorLogin && (
|
||||||
<FontAwesomeIcon icon={faBasketShopping} className="ms-1 buyer-icon" title="Zakladatel / objednávající" />
|
<OverlayTrigger placement="top" overlay={<Tooltip>Zakladatel / objednávající</Tooltip>}>
|
||||||
|
<span className="ms-1"><FontAwesomeIcon icon={faBasketShopping} className="buyer-icon" /></span>
|
||||||
|
</OverlayTrigger>
|
||||||
)}
|
)}
|
||||||
{member.paid && (
|
{member.paid && (
|
||||||
<FontAwesomeIcon icon={faCircleCheck} className="ms-1 text-success" title="Zaplaceno" />
|
<OverlayTrigger placement="top" overlay={<Tooltip>Zaplaceno</Tooltip>}>
|
||||||
|
<span className="ms-1"><FontAwesomeIcon icon={faCircleCheck} className="text-success" /></span>
|
||||||
|
</OverlayTrigger>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
@@ -318,10 +359,10 @@ export default function OrderGroupsPage() {
|
|||||||
ref={memberLogin === login ? inputRef : undefined}
|
ref={memberLogin === login ? inputRef : undefined}
|
||||||
type="number"
|
type="number"
|
||||||
size="sm"
|
size="sm"
|
||||||
value={editAmounts[amountKey]}
|
value={editAmounts[key]}
|
||||||
onChange={e => setEditAmounts(prev => ({ ...prev, [amountKey]: e.target.value }))}
|
onChange={e => setEditAmounts(prev => ({ ...prev, [key]: e.target.value }))}
|
||||||
onKeyDown={e => { e.stopPropagation(); if (e.key === 'Enter') handleSaveAmount(group.id, memberLogin); if (e.key === 'Escape') setEditAmounts(prev => { const n = { ...prev }; delete n[amountKey]; return n; }); }}
|
onKeyDown={e => { e.stopPropagation(); if (e.key === 'Enter') handleSaveAmount(group.id, memberLogin); if (e.key === 'Escape') setEditAmounts(prev => { const n = { ...prev }; delete n[key]; return n; }); }}
|
||||||
style={{ width: 80 }}
|
style={{ width: 75 }}
|
||||||
autoFocus={memberLogin === login}
|
autoFocus={memberLogin === login}
|
||||||
/>
|
/>
|
||||||
<Button size="sm" variant="outline-success" onClick={() => handleSaveAmount(group.id, memberLogin)}>✓</Button>
|
<Button size="sm" variant="outline-success" onClick={() => handleSaveAmount(group.id, memberLogin)}>✓</Button>
|
||||||
@@ -329,22 +370,60 @@ export default function OrderGroupsPage() {
|
|||||||
) : (
|
) : (
|
||||||
<span
|
<span
|
||||||
style={{ cursor: canEdit ? 'pointer' : undefined }}
|
style={{ cursor: canEdit ? 'pointer' : undefined }}
|
||||||
onClick={() => canEdit && setEditAmounts(prev => ({ ...prev, [amountKey]: String(member.amount ?? '') }))}
|
onClick={() => canEdit && setEditAmounts(prev => ({ ...prev, [key]: String(member.amount ?? '') }))}
|
||||||
title={canEdit ? 'Klikněte pro úpravu' : undefined}
|
title={canEdit ? 'Klikněte pro úpravu' : undefined}
|
||||||
>
|
>
|
||||||
{member.amount != null ? `${member.amount} Kč` : <span className="text-muted">—</span>}
|
{member.amount != null ? `${member.amount} Kč` : <span className="text-muted">—</span>}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
{canEdit && editingSurcharge ? (
|
||||||
|
<div className="d-flex gap-1">
|
||||||
|
<Form.Control
|
||||||
|
type="text"
|
||||||
|
size="sm"
|
||||||
|
placeholder="popis"
|
||||||
|
value={editSurcharges[key]?.text ?? ''}
|
||||||
|
onChange={e => setEditSurcharges(prev => ({ ...prev, [key]: { ...prev[key], text: e.target.value } }))}
|
||||||
|
onKeyDown={e => { e.stopPropagation(); if (e.key === 'Enter') handleSaveSurcharge(group.id, memberLogin); if (e.key === 'Escape') setEditSurcharges(prev => { const n = { ...prev }; delete n[key]; return n; }); }}
|
||||||
|
style={{ width: 80 }}
|
||||||
|
autoFocus
|
||||||
|
/>
|
||||||
|
<Form.Control
|
||||||
|
type="number"
|
||||||
|
size="sm"
|
||||||
|
placeholder="Kč"
|
||||||
|
value={editSurcharges[key]?.amount ?? ''}
|
||||||
|
onChange={e => setEditSurcharges(prev => ({ ...prev, [key]: { ...prev[key], amount: e.target.value } }))}
|
||||||
|
onKeyDown={e => { e.stopPropagation(); if (e.key === 'Enter') handleSaveSurcharge(group.id, memberLogin); if (e.key === 'Escape') setEditSurcharges(prev => { const n = { ...prev }; delete n[key]; return n; }); }}
|
||||||
|
style={{ width: 60 }}
|
||||||
|
/>
|
||||||
|
<Button size="sm" variant="outline-success" onClick={() => handleSaveSurcharge(group.id, memberLogin)}>✓</Button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<span
|
||||||
|
style={{ cursor: canEdit ? 'pointer' : undefined }}
|
||||||
|
onClick={() => canEdit && setEditSurcharges(prev => ({ ...prev, [key]: { text: member.surchargeText ?? '', amount: member.surchargeAmount != null ? String(member.surchargeAmount) : '' } }))}
|
||||||
|
title={canEdit ? 'Klikněte pro úpravu příplatku' : undefined}
|
||||||
|
>
|
||||||
|
{member.surchargeAmount != null && member.surchargeAmount > 0 ? (
|
||||||
|
<small>{member.surchargeText ? `${member.surchargeText}: ` : ''}<strong>{member.surchargeAmount} Kč</strong></small>
|
||||||
|
) : (
|
||||||
|
<small className="text-muted">—</small>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{canEdit && editingNote ? (
|
{canEdit && editingNote ? (
|
||||||
<div className="d-flex gap-1">
|
<div className="d-flex gap-1">
|
||||||
<Form.Control
|
<Form.Control
|
||||||
type="text"
|
type="text"
|
||||||
size="sm"
|
size="sm"
|
||||||
value={editNotes[noteKey]}
|
value={editNotes[key]}
|
||||||
onChange={e => setEditNotes(prev => ({ ...prev, [noteKey]: e.target.value }))}
|
onChange={e => setEditNotes(prev => ({ ...prev, [key]: e.target.value }))}
|
||||||
onKeyDown={e => { e.stopPropagation(); if (e.key === 'Enter') handleSaveNote(group.id, memberLogin); if (e.key === 'Escape') setEditNotes(prev => { const n = { ...prev }; delete n[noteKey]; return n; }); }}
|
onKeyDown={e => { e.stopPropagation(); if (e.key === 'Enter') handleSaveNote(group.id, memberLogin); if (e.key === 'Escape') setEditNotes(prev => { const n = { ...prev }; delete n[key]; return n; }); }}
|
||||||
autoFocus
|
autoFocus
|
||||||
/>
|
/>
|
||||||
<Button size="sm" variant="outline-success" onClick={() => handleSaveNote(group.id, memberLogin)}>✓</Button>
|
<Button size="sm" variant="outline-success" onClick={() => handleSaveNote(group.id, memberLogin)}>✓</Button>
|
||||||
@@ -352,13 +431,18 @@ export default function OrderGroupsPage() {
|
|||||||
) : (
|
) : (
|
||||||
<span
|
<span
|
||||||
style={{ cursor: canEdit ? 'pointer' : undefined }}
|
style={{ cursor: canEdit ? 'pointer' : undefined }}
|
||||||
onClick={() => canEdit && setEditNotes(prev => ({ ...prev, [noteKey]: member.note ?? '' }))}
|
onClick={() => canEdit && setEditNotes(prev => ({ ...prev, [key]: member.note ?? '' }))}
|
||||||
title={canEdit ? 'Klikněte pro úpravu poznámky' : undefined}
|
title={canEdit ? 'Klikněte pro úpravu poznámky' : undefined}
|
||||||
>
|
>
|
||||||
<small className="text-muted">{member.note || '—'}</small>
|
<small className="text-muted">{member.note || '—'}</small>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
|
<td className="text-end">
|
||||||
|
<small className={memberTotal > 0 ? 'fw-bold' : 'text-muted'}>
|
||||||
|
{memberTotal > 0 ? `${memberTotal} Kč` : '—'}
|
||||||
|
</small>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div className="d-flex gap-1 justify-content-end">
|
<div className="d-flex gap-1 justify-content-end">
|
||||||
{canManageMembers(group) && (isCreator || memberLogin === login) && (memberLogin !== group.creatorLogin) && (
|
{canManageMembers(group) && (isCreator || memberLogin === login) && (memberLogin !== group.creatorLogin) && (
|
||||||
@@ -377,6 +461,21 @@ export default function OrderGroupsPage() {
|
|||||||
</tbody>
|
</tbody>
|
||||||
</Table>
|
</Table>
|
||||||
|
|
||||||
|
{/* Souhrn poplatků a slevy */}
|
||||||
|
{(totalFees > 0 || (group.discountValue != null && group.discountValue > 0)) && (
|
||||||
|
<div className="px-3 py-2 border-top d-flex gap-3 flex-wrap" style={{ fontSize: '0.85em', color: 'var(--luncher-text-muted)' }}>
|
||||||
|
{group.fees != null && group.fees > 0 && <span>Poplatky: <strong>{group.fees} Kč</strong></span>}
|
||||||
|
{group.shipping != null && group.shipping > 0 && <span>Doprava: <strong>{group.shipping} Kč</strong></span>}
|
||||||
|
{group.tip != null && group.tip > 0 && <span>Spropitné: <strong>{group.tip} Kč</strong></span>}
|
||||||
|
{feeShare > 0 && <span>→ <strong>{feeShare} Kč</strong>/os.</span>}
|
||||||
|
{group.discountValue != null && group.discountValue > 0 && (
|
||||||
|
<span className="text-success">
|
||||||
|
Sleva: <strong>{group.discountType === 'percent' ? `${group.discountValue}%` : `${group.discountValue} Kč`}</strong>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Časy objednání a doručení */}
|
{/* Časy objednání a doručení */}
|
||||||
{isOrdered && (
|
{isOrdered && (
|
||||||
<div className="px-3 py-2 border-top">
|
<div className="px-3 py-2 border-top">
|
||||||
@@ -472,6 +571,21 @@ export default function OrderGroupsPage() {
|
|||||||
bankAccountHolder={settings.holderName}
|
bankAccountHolder={settings.holderName}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{feesModal && (
|
||||||
|
<EditGroupFeesModal
|
||||||
|
isOpen={!!feesModal}
|
||||||
|
onClose={() => setFeesModal(null)}
|
||||||
|
group={feesModal}
|
||||||
|
onSaved={newData => {
|
||||||
|
if (newData) {
|
||||||
|
setData(newData);
|
||||||
|
socket.emit?.('message', newData as ClientData);
|
||||||
|
}
|
||||||
|
setFeesModal(null);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,6 +147,20 @@ export async function markGroupMemberPaid(login: string, groupId: string, date?:
|
|||||||
return saveExtraData(data, date);
|
return saveExtraData(data, date);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function updateGroupFees(login: string, groupId: string, fees?: number, shipping?: number, tip?: number, discountType?: string, discountValue?: number, date?: Date): Promise<ClientData> {
|
||||||
|
const data = await getExtraData(date);
|
||||||
|
const group = findGroup(data, groupId);
|
||||||
|
if (!group) throw new Error('Skupina nebyla nalezena');
|
||||||
|
if (group.creatorLogin !== login) throw new Error('Poplatky může měnit pouze zakladatel');
|
||||||
|
if (group.state === GroupState.ORDERED) throw new Error('Skupinu ve stavu "objednáno" nelze upravovat');
|
||||||
|
if (fees !== undefined) group.fees = fees > 0 ? fees : undefined;
|
||||||
|
if (shipping !== undefined) group.shipping = shipping > 0 ? shipping : undefined;
|
||||||
|
if (tip !== undefined) group.tip = tip > 0 ? tip : undefined;
|
||||||
|
if (discountType !== undefined) group.discountType = (discountType as any) || undefined;
|
||||||
|
if (discountValue !== undefined) group.discountValue = discountValue > 0 ? discountValue : undefined;
|
||||||
|
return saveExtraData(data, date);
|
||||||
|
}
|
||||||
|
|
||||||
export async function updateGroupTimes(login: string, groupId: string, orderedAt?: string, deliveryAt?: string, date?: Date): Promise<ClientData> {
|
export async function updateGroupTimes(login: string, groupId: string, orderedAt?: string, deliveryAt?: string, date?: Date): Promise<ClientData> {
|
||||||
const data = await getExtraData(date);
|
const data = await getExtraData(date);
|
||||||
const group = findGroup(data, groupId);
|
const group = findGroup(data, groupId);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import express, { Request } from "express";
|
|||||||
import { getLogin } from "../auth";
|
import { getLogin } from "../auth";
|
||||||
import { parseToken } from "../utils";
|
import { parseToken } from "../utils";
|
||||||
import { getWebsocket } from "../websocket";
|
import { getWebsocket } from "../websocket";
|
||||||
import { createGroup, deleteGroup, addGroupMember, removeGroupMember, updateGroupMember, setGroupState, updateGroupTimes } from "../groups";
|
import { createGroup, deleteGroup, addGroupMember, removeGroupMember, updateGroupMember, setGroupState, updateGroupTimes, updateGroupFees } from "../groups";
|
||||||
import { GroupState } from "../../../types/gen/types.gen";
|
import { GroupState } from "../../../types/gen/types.gen";
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
@@ -109,6 +109,32 @@ router.post("/setState", async (req: Request, res, next) => {
|
|||||||
} catch (e: any) { next(e); }
|
} catch (e: any) { next(e); }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.post("/updateFees", async (req: Request, res, next) => {
|
||||||
|
const login = getLogin(parseToken(req));
|
||||||
|
const { id, fees, shipping, tip, discountType, discountValue } = req.body ?? {};
|
||||||
|
if (!id) return res.status(400).json({ error: 'Nebylo předáno ID skupiny' });
|
||||||
|
if (fees !== undefined && (typeof fees !== 'number' || !Number.isFinite(fees) || fees < 0)) {
|
||||||
|
return res.status(400).json({ error: 'Neplatná výše poplatků' });
|
||||||
|
}
|
||||||
|
if (shipping !== undefined && (typeof shipping !== 'number' || !Number.isFinite(shipping) || shipping < 0)) {
|
||||||
|
return res.status(400).json({ error: 'Neplatná výše dopravy' });
|
||||||
|
}
|
||||||
|
if (tip !== undefined && (typeof tip !== 'number' || !Number.isFinite(tip) || tip < 0)) {
|
||||||
|
return res.status(400).json({ error: 'Neplatná výše spropitného' });
|
||||||
|
}
|
||||||
|
if (discountType !== undefined && discountType !== '' && !['percent', 'fixed'].includes(discountType)) {
|
||||||
|
return res.status(400).json({ error: 'Neplatný typ slevy' });
|
||||||
|
}
|
||||||
|
if (discountValue !== undefined && (typeof discountValue !== 'number' || !Number.isFinite(discountValue) || discountValue < 0)) {
|
||||||
|
return res.status(400).json({ error: 'Neplatná výše slevy' });
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const data = await updateGroupFees(login, id, fees, shipping, tip, discountType, discountValue);
|
||||||
|
broadcastExtra(data);
|
||||||
|
res.status(200).json(data);
|
||||||
|
} catch (e: any) { next(e); }
|
||||||
|
});
|
||||||
|
|
||||||
router.post("/updateTimes", async (req: Request, res, next) => {
|
router.post("/updateTimes", async (req: Request, res, next) => {
|
||||||
const login = getLogin(parseToken(req));
|
const login = getLogin(parseToken(req));
|
||||||
const { id, orderedAt, deliveryAt } = req.body ?? {};
|
const { id, orderedAt, deliveryAt } = req.body ?? {};
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { getLogin } from "../auth";
|
|||||||
import { parseToken, formatDate } from "../utils";
|
import { parseToken, formatDate } from "../utils";
|
||||||
import { generateQr } from "../qr";
|
import { generateQr } from "../qr";
|
||||||
import { addPendingQr } from "../pizza";
|
import { addPendingQr } from "../pizza";
|
||||||
|
import { emitToUser } from "../websocket";
|
||||||
import { GenerateQrData } from "../../../types";
|
import { GenerateQrData } from "../../../types";
|
||||||
import crypto from "crypto";
|
import crypto from "crypto";
|
||||||
|
|
||||||
@@ -48,15 +49,17 @@ router.post("/generate", async (req: Request<{}, any, GenerateQrData["body"]>, r
|
|||||||
const id = crypto.randomUUID();
|
const id = crypto.randomUUID();
|
||||||
await generateQr(recipient.login, bankAccount, bankAccountHolder, recipient.amount, recipient.purpose, id);
|
await generateQr(recipient.login, bankAccount, bankAccountHolder, recipient.amount, recipient.purpose, id);
|
||||||
|
|
||||||
// Uložit jako nevyřízený QR kód
|
// Uložit jako nevyřízený QR kód a okamžitě doručit příjemci
|
||||||
await addPendingQr(recipient.login, {
|
const pendingQr = {
|
||||||
id,
|
id,
|
||||||
date: today,
|
date: today,
|
||||||
creator: login,
|
creator: login,
|
||||||
totalPrice: recipient.amount,
|
totalPrice: recipient.amount,
|
||||||
purpose: recipient.purpose,
|
purpose: recipient.purpose,
|
||||||
...(groupId ? { groupId } : {}),
|
...(groupId ? { groupId } : {}),
|
||||||
});
|
};
|
||||||
|
await addPendingQr(recipient.login, pendingQr);
|
||||||
|
emitToUser(recipient.login, 'pendingQr', pendingQr);
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(200).json({ success: true, count: recipients.length });
|
res.status(200).json({ success: true, count: recipients.length });
|
||||||
|
|||||||
+11
-2
@@ -11,6 +11,12 @@ export const initWebsocket = (server: any) => {
|
|||||||
io.on("connection", (socket) => {
|
io.on("connection", (socket) => {
|
||||||
console.log(`New client connected: ${socket.id}`);
|
console.log(`New client connected: ${socket.id}`);
|
||||||
|
|
||||||
|
socket.on("join", (login: string) => {
|
||||||
|
if (login && typeof login === "string") {
|
||||||
|
socket.join(`user:${login}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
socket.on("message", (message) => {
|
socket.on("message", (message) => {
|
||||||
io.emit("message", message);
|
io.emit("message", message);
|
||||||
});
|
});
|
||||||
@@ -22,6 +28,9 @@ export const initWebsocket = (server: any) => {
|
|||||||
return io;
|
return io;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getWebsocket = () => {
|
export const getWebsocket = () => io;
|
||||||
return io;
|
|
||||||
|
/** Pošle event konkrétnímu přihlášenému uživateli (pokud je připojen). */
|
||||||
|
export const emitToUser = (login: string, event: string, data: unknown) => {
|
||||||
|
io.to(`user:${login}`).emit(event, data);
|
||||||
}
|
}
|
||||||
@@ -96,6 +96,8 @@ paths:
|
|||||||
$ref: "./paths/groups/setState.yml"
|
$ref: "./paths/groups/setState.yml"
|
||||||
/groups/updateTimes:
|
/groups/updateTimes:
|
||||||
$ref: "./paths/groups/updateTimes.yml"
|
$ref: "./paths/groups/updateTimes.yml"
|
||||||
|
/groups/updateFees:
|
||||||
|
$ref: "./paths/groups/updateFees.yml"
|
||||||
|
|
||||||
# Správa obchodů (/api/stores)
|
# Správa obchodů (/api/stores)
|
||||||
/stores:
|
/stores:
|
||||||
|
|||||||
Generated
+594
@@ -0,0 +1,594 @@
|
|||||||
|
{
|
||||||
|
"name": "@luncher/types",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "@luncher/types",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"devDependencies": {
|
||||||
|
"@hey-api/client-fetch": "^0.8.2",
|
||||||
|
"@hey-api/openapi-ts": "^0.64.7",
|
||||||
|
"typescript": "^5.9.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@hey-api/client-fetch": {
|
||||||
|
"version": "0.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@hey-api/client-fetch/-/client-fetch-0.8.2.tgz",
|
||||||
|
"integrity": "sha512-61T4UGfAzY5345vMxWDX8qnSTNRJcOpWuZyvNu3vNebCTLPwMQAM85mhEuBoACdWeRtLhNoUjU0UR5liRyD1bA==",
|
||||||
|
"deprecated": "Starting with v0.73.0, this package is bundled directly inside @hey-api/openapi-ts.",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/hey-api"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@hey-api/json-schema-ref-parser": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@hey-api/json-schema-ref-parser/-/json-schema-ref-parser-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-F6LSkttZcT/XiX3ydeDqTY3uRN3BLJMwyMTk4kg/ichZlKUp3+3Odv0WokSmXGSoZGTW/N66FROMYAm5NPdJlA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@jsdevtools/ono": "^7.1.3",
|
||||||
|
"@types/json-schema": "^7.0.15",
|
||||||
|
"js-yaml": "^4.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/hey-api"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@hey-api/openapi-ts": {
|
||||||
|
"version": "0.64.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.64.7.tgz",
|
||||||
|
"integrity": "sha512-xpaBzdGAKz7cPuGah1GZWl3zTZquOXRnwmpVCQKEUpvDtSYWBLjSxtAYIqDBjwJkuNHcakZBIWLcappx7slc2g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@hey-api/json-schema-ref-parser": "1.0.2",
|
||||||
|
"c12": "2.0.1",
|
||||||
|
"commander": "13.0.0",
|
||||||
|
"handlebars": "4.7.8"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"openapi-ts": "bin/index.cjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || ^20.9.0 || >=22.11.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/hey-api"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "^5.5.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@jsdevtools/ono": {
|
||||||
|
"version": "7.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz",
|
||||||
|
"integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@types/json-schema": {
|
||||||
|
"version": "7.0.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
||||||
|
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/acorn": {
|
||||||
|
"version": "8.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
|
||||||
|
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"acorn": "bin/acorn"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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,
|
||||||
|
"license": "Python-2.0"
|
||||||
|
},
|
||||||
|
"node_modules/c12": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/c12/-/c12-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-Z4JgsKXHG37C6PYUtIxCfLJZvo6FyhHJoClwwb9ftUkLpPSkuYqn6Tr+vnaN8hymm0kIbcg6Ey3kv/Q71k5w/A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"chokidar": "^4.0.1",
|
||||||
|
"confbox": "^0.1.7",
|
||||||
|
"defu": "^6.1.4",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
|
"giget": "^1.2.3",
|
||||||
|
"jiti": "^2.3.0",
|
||||||
|
"mlly": "^1.7.1",
|
||||||
|
"ohash": "^1.1.4",
|
||||||
|
"pathe": "^1.1.2",
|
||||||
|
"perfect-debounce": "^1.0.0",
|
||||||
|
"pkg-types": "^1.2.0",
|
||||||
|
"rc9": "^2.1.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"magicast": "^0.3.5"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"magicast": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/chokidar": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"readdirp": "^4.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14.16.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/chownr": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/citty": {
|
||||||
|
"version": "0.1.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz",
|
||||||
|
"integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"consola": "^3.2.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/commander": {
|
||||||
|
"version": "13.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-13.0.0.tgz",
|
||||||
|
"integrity": "sha512-oPYleIY8wmTVzkvQq10AEok6YcTC4sRUBl8F9gVuwchGVUCTbl/vhLTaQqutuuySYOsu8YTgV+OxKc/8Yvx+mQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/confbox": {
|
||||||
|
"version": "0.1.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
|
||||||
|
"integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/consola": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/consola/-/consola-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "^14.18.0 || >=16.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/defu": {
|
||||||
|
"version": "6.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz",
|
||||||
|
"integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/destr": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/destr/-/destr-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/dotenv": {
|
||||||
|
"version": "16.4.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz",
|
||||||
|
"integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://dotenvx.com"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fs-minipass": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"minipass": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fs-minipass/node_modules/minipass": {
|
||||||
|
"version": "3.3.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
|
||||||
|
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"yallist": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/giget": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/giget/-/giget-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-r1ekGw/Bgpi3HLV3h1MRBIlSAdHoIMklpaQ3OQLFcRw9PwAj2rqigvIbg+dBUI51OxVI2jsEtDywDBjSiuf7Ug==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"citty": "^0.1.6",
|
||||||
|
"consola": "^3.4.0",
|
||||||
|
"defu": "^6.1.4",
|
||||||
|
"node-fetch-native": "^1.6.6",
|
||||||
|
"nypm": "^0.5.4",
|
||||||
|
"pathe": "^2.0.3",
|
||||||
|
"tar": "^6.2.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"giget": "dist/cli.mjs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/giget/node_modules/pathe": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/handlebars": {
|
||||||
|
"version": "4.7.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
|
||||||
|
"integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"minimist": "^1.2.5",
|
||||||
|
"neo-async": "^2.6.2",
|
||||||
|
"source-map": "^0.6.1",
|
||||||
|
"wordwrap": "^1.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"handlebars": "bin/handlebars"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.7"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"uglify-js": "^3.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/jiti": {
|
||||||
|
"version": "2.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
|
||||||
|
"integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"jiti": "lib/jiti-cli.mjs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"argparse": "^2.0.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"js-yaml": "bin/js-yaml.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/minimist": {
|
||||||
|
"version": "1.2.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
||||||
|
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/minipass": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/minizlib": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"minipass": "^3.0.0",
|
||||||
|
"yallist": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/minizlib/node_modules/minipass": {
|
||||||
|
"version": "3.3.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
|
||||||
|
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"yallist": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mkdirp": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"mkdirp": "bin/cmd.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mlly": {
|
||||||
|
"version": "1.7.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz",
|
||||||
|
"integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"acorn": "^8.14.0",
|
||||||
|
"pathe": "^2.0.1",
|
||||||
|
"pkg-types": "^1.3.0",
|
||||||
|
"ufo": "^1.5.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mlly/node_modules/pathe": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/neo-async": {
|
||||||
|
"version": "2.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
|
||||||
|
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/node-fetch-native": {
|
||||||
|
"version": "1.6.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.6.tgz",
|
||||||
|
"integrity": "sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/nypm": {
|
||||||
|
"version": "0.5.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/nypm/-/nypm-0.5.4.tgz",
|
||||||
|
"integrity": "sha512-X0SNNrZiGU8/e/zAB7sCTtdxWTMSIO73q+xuKgglm2Yvzwlo8UoC5FNySQFCvl84uPaeADkqHUZUkWy4aH4xOA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"citty": "^0.1.6",
|
||||||
|
"consola": "^3.4.0",
|
||||||
|
"pathe": "^2.0.3",
|
||||||
|
"pkg-types": "^1.3.1",
|
||||||
|
"tinyexec": "^0.3.2",
|
||||||
|
"ufo": "^1.5.4"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"nypm": "dist/cli.mjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^14.16.0 || >=16.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/nypm/node_modules/pathe": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/ohash": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/pathe": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/perfect-debounce": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/pkg-types": {
|
||||||
|
"version": "1.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
|
||||||
|
"integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"confbox": "^0.1.8",
|
||||||
|
"mlly": "^1.7.4",
|
||||||
|
"pathe": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pkg-types/node_modules/pathe": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/rc9": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"defu": "^6.1.4",
|
||||||
|
"destr": "^2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/readdirp": {
|
||||||
|
"version": "4.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
|
||||||
|
"integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14.18.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/source-map": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||||
|
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tar": {
|
||||||
|
"version": "6.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
|
||||||
|
"integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
|
||||||
|
"deprecated": "Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"chownr": "^2.0.0",
|
||||||
|
"fs-minipass": "^2.0.0",
|
||||||
|
"minipass": "^5.0.0",
|
||||||
|
"minizlib": "^2.1.1",
|
||||||
|
"mkdirp": "^1.0.3",
|
||||||
|
"yallist": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tinyexec": {
|
||||||
|
"version": "0.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
|
||||||
|
"integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/typescript": {
|
||||||
|
"version": "5.9.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||||
|
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"bin": {
|
||||||
|
"tsc": "bin/tsc",
|
||||||
|
"tsserver": "bin/tsserver"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.17"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ufo": {
|
||||||
|
"version": "1.5.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz",
|
||||||
|
"integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/uglify-js": {
|
||||||
|
"version": "3.19.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz",
|
||||||
|
"integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
|
"optional": true,
|
||||||
|
"bin": {
|
||||||
|
"uglifyjs": "bin/uglifyjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/wordwrap": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/yallist": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
post:
|
||||||
|
operationId: updateGroupFees
|
||||||
|
summary: Aktualizuje skupinové poplatky a slevu (pouze zakladatel, pouze otevřená skupina).
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
description: ID skupiny
|
||||||
|
type: string
|
||||||
|
fees:
|
||||||
|
description: Poplatky (Kč)
|
||||||
|
type: number
|
||||||
|
shipping:
|
||||||
|
description: Doprava (Kč)
|
||||||
|
type: number
|
||||||
|
tip:
|
||||||
|
description: Spropitné (Kč)
|
||||||
|
type: number
|
||||||
|
discountType:
|
||||||
|
description: Typ slevy
|
||||||
|
type: string
|
||||||
|
enum: [percent, fixed]
|
||||||
|
discountValue:
|
||||||
|
description: Hodnota slevy
|
||||||
|
type: number
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
$ref: "../../api.yml#/components/responses/ClientDataResponse"
|
||||||
@@ -752,6 +752,22 @@ OrderGroup:
|
|||||||
deliveryAt:
|
deliveryAt:
|
||||||
description: Očekávaný čas doručení ve formátu HH:MM
|
description: Očekávaný čas doručení ve formátu HH:MM
|
||||||
type: string
|
type: string
|
||||||
|
fees:
|
||||||
|
description: Poplatky (balení apod.) celkem v Kč
|
||||||
|
type: number
|
||||||
|
shipping:
|
||||||
|
description: Doprava v Kč
|
||||||
|
type: number
|
||||||
|
tip:
|
||||||
|
description: Spropitné v Kč
|
||||||
|
type: number
|
||||||
|
discountType:
|
||||||
|
description: Typ slevy aplikované na objednávku
|
||||||
|
type: string
|
||||||
|
enum: [percent, fixed]
|
||||||
|
discountValue:
|
||||||
|
description: Hodnota slevy (procenta nebo Kč)
|
||||||
|
type: number
|
||||||
|
|
||||||
# --- NEVYŘÍZENÉ QR KÓDY ---
|
# --- NEVYŘÍZENÉ QR KÓDY ---
|
||||||
PendingQr:
|
PendingQr:
|
||||||
|
|||||||
+53
-48
@@ -4,12 +4,12 @@
|
|||||||
|
|
||||||
"@hey-api/client-fetch@^0.8.2":
|
"@hey-api/client-fetch@^0.8.2":
|
||||||
version "0.8.2"
|
version "0.8.2"
|
||||||
resolved "https://registry.yarnpkg.com/@hey-api/client-fetch/-/client-fetch-0.8.2.tgz#675aadfbc9478bb8eef5679f11a9334258dff4c8"
|
resolved "https://registry.npmjs.org/@hey-api/client-fetch/-/client-fetch-0.8.2.tgz"
|
||||||
integrity sha512-61T4UGfAzY5345vMxWDX8qnSTNRJcOpWuZyvNu3vNebCTLPwMQAM85mhEuBoACdWeRtLhNoUjU0UR5liRyD1bA==
|
integrity sha512-61T4UGfAzY5345vMxWDX8qnSTNRJcOpWuZyvNu3vNebCTLPwMQAM85mhEuBoACdWeRtLhNoUjU0UR5liRyD1bA==
|
||||||
|
|
||||||
"@hey-api/json-schema-ref-parser@1.0.2":
|
"@hey-api/json-schema-ref-parser@1.0.2":
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@hey-api/json-schema-ref-parser/-/json-schema-ref-parser-1.0.2.tgz#c3824c5d9d531eeb5c2b2557857a8ad20b5c75a7"
|
resolved "https://registry.npmjs.org/@hey-api/json-schema-ref-parser/-/json-schema-ref-parser-1.0.2.tgz"
|
||||||
integrity sha512-F6LSkttZcT/XiX3ydeDqTY3uRN3BLJMwyMTk4kg/ichZlKUp3+3Odv0WokSmXGSoZGTW/N66FROMYAm5NPdJlA==
|
integrity sha512-F6LSkttZcT/XiX3ydeDqTY3uRN3BLJMwyMTk4kg/ichZlKUp3+3Odv0WokSmXGSoZGTW/N66FROMYAm5NPdJlA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@jsdevtools/ono" "^7.1.3"
|
"@jsdevtools/ono" "^7.1.3"
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
"@hey-api/openapi-ts@^0.64.7":
|
"@hey-api/openapi-ts@^0.64.7":
|
||||||
version "0.64.7"
|
version "0.64.7"
|
||||||
resolved "https://registry.yarnpkg.com/@hey-api/openapi-ts/-/openapi-ts-0.64.7.tgz#f239d268b4a35b91f5ff25479d15578feb01f365"
|
resolved "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.64.7.tgz"
|
||||||
integrity sha512-xpaBzdGAKz7cPuGah1GZWl3zTZquOXRnwmpVCQKEUpvDtSYWBLjSxtAYIqDBjwJkuNHcakZBIWLcappx7slc2g==
|
integrity sha512-xpaBzdGAKz7cPuGah1GZWl3zTZquOXRnwmpVCQKEUpvDtSYWBLjSxtAYIqDBjwJkuNHcakZBIWLcappx7slc2g==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@hey-api/json-schema-ref-parser" "1.0.2"
|
"@hey-api/json-schema-ref-parser" "1.0.2"
|
||||||
@@ -28,27 +28,27 @@
|
|||||||
|
|
||||||
"@jsdevtools/ono@^7.1.3":
|
"@jsdevtools/ono@^7.1.3":
|
||||||
version "7.1.3"
|
version "7.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/@jsdevtools/ono/-/ono-7.1.3.tgz#9df03bbd7c696a5c58885c34aa06da41c8543796"
|
resolved "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz"
|
||||||
integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==
|
integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==
|
||||||
|
|
||||||
"@types/json-schema@^7.0.15":
|
"@types/json-schema@^7.0.15":
|
||||||
version "7.0.15"
|
version "7.0.15"
|
||||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
|
resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz"
|
||||||
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
|
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
|
||||||
|
|
||||||
acorn@^8.14.0:
|
acorn@^8.14.0:
|
||||||
version "8.14.0"
|
version "8.14.0"
|
||||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0"
|
resolved "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz"
|
||||||
integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==
|
integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==
|
||||||
|
|
||||||
argparse@^2.0.1:
|
argparse@^2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
|
resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz"
|
||||||
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
|
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
|
||||||
|
|
||||||
c12@2.0.1:
|
c12@2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/c12/-/c12-2.0.1.tgz#5702d280b31a08abba39833494c9b1202f0f5aec"
|
resolved "https://registry.npmjs.org/c12/-/c12-2.0.1.tgz"
|
||||||
integrity sha512-Z4JgsKXHG37C6PYUtIxCfLJZvo6FyhHJoClwwb9ftUkLpPSkuYqn6Tr+vnaN8hymm0kIbcg6Ey3kv/Q71k5w/A==
|
integrity sha512-Z4JgsKXHG37C6PYUtIxCfLJZvo6FyhHJoClwwb9ftUkLpPSkuYqn6Tr+vnaN8hymm0kIbcg6Ey3kv/Q71k5w/A==
|
||||||
dependencies:
|
dependencies:
|
||||||
chokidar "^4.0.1"
|
chokidar "^4.0.1"
|
||||||
@@ -66,63 +66,63 @@ c12@2.0.1:
|
|||||||
|
|
||||||
chokidar@^4.0.1:
|
chokidar@^4.0.1:
|
||||||
version "4.0.3"
|
version "4.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30"
|
resolved "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz"
|
||||||
integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==
|
integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==
|
||||||
dependencies:
|
dependencies:
|
||||||
readdirp "^4.0.1"
|
readdirp "^4.0.1"
|
||||||
|
|
||||||
chownr@^2.0.0:
|
chownr@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece"
|
resolved "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz"
|
||||||
integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==
|
integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==
|
||||||
|
|
||||||
citty@^0.1.6:
|
citty@^0.1.6:
|
||||||
version "0.1.6"
|
version "0.1.6"
|
||||||
resolved "https://registry.yarnpkg.com/citty/-/citty-0.1.6.tgz#0f7904da1ed4625e1a9ea7e0fa780981aab7c5e4"
|
resolved "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz"
|
||||||
integrity sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==
|
integrity sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
consola "^3.2.3"
|
consola "^3.2.3"
|
||||||
|
|
||||||
commander@13.0.0:
|
commander@13.0.0:
|
||||||
version "13.0.0"
|
version "13.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-13.0.0.tgz#1b161f60ee3ceb8074583a0f95359a4f8701845c"
|
resolved "https://registry.npmjs.org/commander/-/commander-13.0.0.tgz"
|
||||||
integrity sha512-oPYleIY8wmTVzkvQq10AEok6YcTC4sRUBl8F9gVuwchGVUCTbl/vhLTaQqutuuySYOsu8YTgV+OxKc/8Yvx+mQ==
|
integrity sha512-oPYleIY8wmTVzkvQq10AEok6YcTC4sRUBl8F9gVuwchGVUCTbl/vhLTaQqutuuySYOsu8YTgV+OxKc/8Yvx+mQ==
|
||||||
|
|
||||||
confbox@^0.1.7, confbox@^0.1.8:
|
confbox@^0.1.7, confbox@^0.1.8:
|
||||||
version "0.1.8"
|
version "0.1.8"
|
||||||
resolved "https://registry.yarnpkg.com/confbox/-/confbox-0.1.8.tgz#820d73d3b3c82d9bd910652c5d4d599ef8ff8b06"
|
resolved "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz"
|
||||||
integrity sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==
|
integrity sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==
|
||||||
|
|
||||||
consola@^3.2.3, consola@^3.4.0:
|
consola@^3.2.3, consola@^3.4.0:
|
||||||
version "3.4.0"
|
version "3.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/consola/-/consola-3.4.0.tgz#4cfc9348fd85ed16a17940b3032765e31061ab88"
|
resolved "https://registry.npmjs.org/consola/-/consola-3.4.0.tgz"
|
||||||
integrity sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==
|
integrity sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==
|
||||||
|
|
||||||
defu@^6.1.4:
|
defu@^6.1.4:
|
||||||
version "6.1.4"
|
version "6.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.4.tgz#4e0c9cf9ff68fe5f3d7f2765cc1a012dfdcb0479"
|
resolved "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz"
|
||||||
integrity sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==
|
integrity sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==
|
||||||
|
|
||||||
destr@^2.0.3:
|
destr@^2.0.3:
|
||||||
version "2.0.3"
|
version "2.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/destr/-/destr-2.0.3.tgz#7f9e97cb3d16dbdca7be52aca1644ce402cfe449"
|
resolved "https://registry.npmjs.org/destr/-/destr-2.0.3.tgz"
|
||||||
integrity sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==
|
integrity sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==
|
||||||
|
|
||||||
dotenv@^16.4.5:
|
dotenv@^16.4.5:
|
||||||
version "16.4.7"
|
version "16.4.7"
|
||||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.7.tgz#0e20c5b82950140aa99be360a8a5f52335f53c26"
|
resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz"
|
||||||
integrity sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==
|
integrity sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==
|
||||||
|
|
||||||
fs-minipass@^2.0.0:
|
fs-minipass@^2.0.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"
|
resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz"
|
||||||
integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==
|
integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==
|
||||||
dependencies:
|
dependencies:
|
||||||
minipass "^3.0.0"
|
minipass "^3.0.0"
|
||||||
|
|
||||||
giget@^1.2.3:
|
giget@^1.2.3:
|
||||||
version "1.2.5"
|
version "1.2.5"
|
||||||
resolved "https://registry.yarnpkg.com/giget/-/giget-1.2.5.tgz#0bd4909356a0da75cc1f2b33538f93adec0d202f"
|
resolved "https://registry.npmjs.org/giget/-/giget-1.2.5.tgz"
|
||||||
integrity sha512-r1ekGw/Bgpi3HLV3h1MRBIlSAdHoIMklpaQ3OQLFcRw9PwAj2rqigvIbg+dBUI51OxVI2jsEtDywDBjSiuf7Ug==
|
integrity sha512-r1ekGw/Bgpi3HLV3h1MRBIlSAdHoIMklpaQ3OQLFcRw9PwAj2rqigvIbg+dBUI51OxVI2jsEtDywDBjSiuf7Ug==
|
||||||
dependencies:
|
dependencies:
|
||||||
citty "^0.1.6"
|
citty "^0.1.6"
|
||||||
@@ -135,7 +135,7 @@ giget@^1.2.3:
|
|||||||
|
|
||||||
handlebars@4.7.8:
|
handlebars@4.7.8:
|
||||||
version "4.7.8"
|
version "4.7.8"
|
||||||
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9"
|
resolved "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz"
|
||||||
integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==
|
integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
minimist "^1.2.5"
|
minimist "^1.2.5"
|
||||||
@@ -147,36 +147,36 @@ handlebars@4.7.8:
|
|||||||
|
|
||||||
jiti@^2.3.0:
|
jiti@^2.3.0:
|
||||||
version "2.4.2"
|
version "2.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/jiti/-/jiti-2.4.2.tgz#d19b7732ebb6116b06e2038da74a55366faef560"
|
resolved "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz"
|
||||||
integrity sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==
|
integrity sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==
|
||||||
|
|
||||||
js-yaml@^4.1.0:
|
js-yaml@^4.1.0:
|
||||||
version "4.1.0"
|
version "4.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
|
resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz"
|
||||||
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
|
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
|
||||||
dependencies:
|
dependencies:
|
||||||
argparse "^2.0.1"
|
argparse "^2.0.1"
|
||||||
|
|
||||||
minimist@^1.2.5:
|
minimist@^1.2.5:
|
||||||
version "1.2.8"
|
version "1.2.8"
|
||||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
|
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz"
|
||||||
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
|
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
|
||||||
|
|
||||||
minipass@^3.0.0:
|
minipass@^3.0.0:
|
||||||
version "3.3.6"
|
version "3.3.6"
|
||||||
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a"
|
resolved "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz"
|
||||||
integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==
|
integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==
|
||||||
dependencies:
|
dependencies:
|
||||||
yallist "^4.0.0"
|
yallist "^4.0.0"
|
||||||
|
|
||||||
minipass@^5.0.0:
|
minipass@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d"
|
resolved "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz"
|
||||||
integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==
|
integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==
|
||||||
|
|
||||||
minizlib@^2.1.1:
|
minizlib@^2.1.1:
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931"
|
resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz"
|
||||||
integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==
|
integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==
|
||||||
dependencies:
|
dependencies:
|
||||||
minipass "^3.0.0"
|
minipass "^3.0.0"
|
||||||
@@ -184,12 +184,12 @@ minizlib@^2.1.1:
|
|||||||
|
|
||||||
mkdirp@^1.0.3:
|
mkdirp@^1.0.3:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz"
|
||||||
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
||||||
|
|
||||||
mlly@^1.7.1, mlly@^1.7.4:
|
mlly@^1.7.1, mlly@^1.7.4:
|
||||||
version "1.7.4"
|
version "1.7.4"
|
||||||
resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.7.4.tgz#3d7295ea2358ec7a271eaa5d000a0f84febe100f"
|
resolved "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz"
|
||||||
integrity sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==
|
integrity sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==
|
||||||
dependencies:
|
dependencies:
|
||||||
acorn "^8.14.0"
|
acorn "^8.14.0"
|
||||||
@@ -199,17 +199,17 @@ mlly@^1.7.1, mlly@^1.7.4:
|
|||||||
|
|
||||||
neo-async@^2.6.2:
|
neo-async@^2.6.2:
|
||||||
version "2.6.2"
|
version "2.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
|
resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz"
|
||||||
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
|
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
|
||||||
|
|
||||||
node-fetch-native@^1.6.6:
|
node-fetch-native@^1.6.6:
|
||||||
version "1.6.6"
|
version "1.6.6"
|
||||||
resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.6.6.tgz#ae1d0e537af35c2c0b0de81cbff37eedd410aa37"
|
resolved "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.6.tgz"
|
||||||
integrity sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==
|
integrity sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==
|
||||||
|
|
||||||
nypm@^0.5.4:
|
nypm@^0.5.4:
|
||||||
version "0.5.4"
|
version "0.5.4"
|
||||||
resolved "https://registry.yarnpkg.com/nypm/-/nypm-0.5.4.tgz#a5ab0d8d37f96342328479f88ef58699f29b3051"
|
resolved "https://registry.npmjs.org/nypm/-/nypm-0.5.4.tgz"
|
||||||
integrity sha512-X0SNNrZiGU8/e/zAB7sCTtdxWTMSIO73q+xuKgglm2Yvzwlo8UoC5FNySQFCvl84uPaeADkqHUZUkWy4aH4xOA==
|
integrity sha512-X0SNNrZiGU8/e/zAB7sCTtdxWTMSIO73q+xuKgglm2Yvzwlo8UoC5FNySQFCvl84uPaeADkqHUZUkWy4aH4xOA==
|
||||||
dependencies:
|
dependencies:
|
||||||
citty "^0.1.6"
|
citty "^0.1.6"
|
||||||
@@ -221,27 +221,32 @@ nypm@^0.5.4:
|
|||||||
|
|
||||||
ohash@^1.1.4:
|
ohash@^1.1.4:
|
||||||
version "1.1.4"
|
version "1.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/ohash/-/ohash-1.1.4.tgz#ae8d83014ab81157d2c285abf7792e2995fadd72"
|
resolved "https://registry.npmjs.org/ohash/-/ohash-1.1.4.tgz"
|
||||||
integrity sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==
|
integrity sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==
|
||||||
|
|
||||||
pathe@^1.1.2:
|
pathe@^1.1.2:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec"
|
resolved "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz"
|
||||||
integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==
|
integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==
|
||||||
|
|
||||||
pathe@^2.0.1, pathe@^2.0.3:
|
pathe@^2.0.1:
|
||||||
version "2.0.3"
|
version "2.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/pathe/-/pathe-2.0.3.tgz#3ecbec55421685b70a9da872b2cff3e1cbed1716"
|
resolved "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz"
|
||||||
|
integrity sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==
|
||||||
|
|
||||||
|
pathe@^2.0.3:
|
||||||
|
version "2.0.3"
|
||||||
|
resolved "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz"
|
||||||
integrity sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==
|
integrity sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==
|
||||||
|
|
||||||
perfect-debounce@^1.0.0:
|
perfect-debounce@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz#9c2e8bc30b169cc984a58b7d5b28049839591d2a"
|
resolved "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz"
|
||||||
integrity sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==
|
integrity sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==
|
||||||
|
|
||||||
pkg-types@^1.2.0, pkg-types@^1.3.0, pkg-types@^1.3.1:
|
pkg-types@^1.2.0, pkg-types@^1.3.0, pkg-types@^1.3.1:
|
||||||
version "1.3.1"
|
version "1.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.3.1.tgz#bd7cc70881192777eef5326c19deb46e890917df"
|
resolved "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz"
|
||||||
integrity sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==
|
integrity sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
confbox "^0.1.8"
|
confbox "^0.1.8"
|
||||||
@@ -250,7 +255,7 @@ pkg-types@^1.2.0, pkg-types@^1.3.0, pkg-types@^1.3.1:
|
|||||||
|
|
||||||
rc9@^2.1.2:
|
rc9@^2.1.2:
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/rc9/-/rc9-2.1.2.tgz#6282ff638a50caa0a91a31d76af4a0b9cbd1080d"
|
resolved "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz"
|
||||||
integrity sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==
|
integrity sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==
|
||||||
dependencies:
|
dependencies:
|
||||||
defu "^6.1.4"
|
defu "^6.1.4"
|
||||||
@@ -258,17 +263,17 @@ rc9@^2.1.2:
|
|||||||
|
|
||||||
readdirp@^4.0.1:
|
readdirp@^4.0.1:
|
||||||
version "4.1.2"
|
version "4.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.1.2.tgz#eb85801435fbf2a7ee58f19e0921b068fc69948d"
|
resolved "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz"
|
||||||
integrity sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==
|
integrity sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==
|
||||||
|
|
||||||
source-map@^0.6.1:
|
source-map@^0.6.1:
|
||||||
version "0.6.1"
|
version "0.6.1"
|
||||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz"
|
||||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||||
|
|
||||||
tar@^6.2.1:
|
tar@^6.2.1:
|
||||||
version "6.2.1"
|
version "6.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a"
|
resolved "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz"
|
||||||
integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==
|
integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==
|
||||||
dependencies:
|
dependencies:
|
||||||
chownr "^2.0.0"
|
chownr "^2.0.0"
|
||||||
@@ -280,30 +285,30 @@ tar@^6.2.1:
|
|||||||
|
|
||||||
tinyexec@^0.3.2:
|
tinyexec@^0.3.2:
|
||||||
version "0.3.2"
|
version "0.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-0.3.2.tgz#941794e657a85e496577995c6eef66f53f42b3d2"
|
resolved "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz"
|
||||||
integrity sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==
|
integrity sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==
|
||||||
|
|
||||||
typescript@^5.9.3:
|
typescript@^5.5.3, typescript@^5.9.3:
|
||||||
version "5.9.3"
|
version "5.9.3"
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.3.tgz#5b4f59e15310ab17a216f5d6cf53ee476ede670f"
|
resolved "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz"
|
||||||
integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==
|
integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==
|
||||||
|
|
||||||
ufo@^1.5.4:
|
ufo@^1.5.4:
|
||||||
version "1.5.4"
|
version "1.5.4"
|
||||||
resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.5.4.tgz#16d6949674ca0c9e0fbbae1fa20a71d7b1ded754"
|
resolved "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz"
|
||||||
integrity sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==
|
integrity sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==
|
||||||
|
|
||||||
uglify-js@^3.1.4:
|
uglify-js@^3.1.4:
|
||||||
version "3.19.3"
|
version "3.19.3"
|
||||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.19.3.tgz#82315e9bbc6f2b25888858acd1fff8441035b77f"
|
resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz"
|
||||||
integrity sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==
|
integrity sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==
|
||||||
|
|
||||||
wordwrap@^1.0.0:
|
wordwrap@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
|
resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz"
|
||||||
integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==
|
integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==
|
||||||
|
|
||||||
yallist@^4.0.0:
|
yallist@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
|
resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"
|
||||||
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
||||||
|
|||||||
Reference in New Issue
Block a user