CognxSafeTrack commited on
Commit
0349430
·
1 Parent(s): c8a4f4b

feat: admin auth login, real WhatsApp Cloud API, Cloudflare R2 storage

Browse files
.env.example CHANGED
@@ -10,6 +10,7 @@ ADMIN_API_KEY= # Strong random secret, e.g. openssl rand -hex 32
10
  WHATSAPP_VERIFY_TOKEN= # Token you set in the Meta App dashboard
11
  WHATSAPP_APP_SECRET= # App Secret from Meta App Settings > Basic
12
  WHATSAPP_ACCESS_TOKEN= # Permanent System User token from Meta Business
 
13
 
14
  # ─── Database ──────────────────────────────────────────────────────────────────
15
  DATABASE_URL=postgresql://user:password@localhost:5432/edtech?schema=public
@@ -30,6 +31,13 @@ STRIPE_WEBHOOK_SECRET= # whsec_... from Stripe dashboard > Webhooks
30
  # ─── OpenAI / AI ───────────────────────────────────────────────────────────────
31
  OPENAI_API_KEY= # sk-...
32
 
 
 
 
 
 
 
 
33
  # ─── Frontend ──────────────────────────────────────────────────────────────────
34
  VITE_CLIENT_URL=https://your-frontend.netlify.app
35
  VITE_WHATSAPP_NUMBER=221771234567 # Without + prefix, for wa.me links
 
10
  WHATSAPP_VERIFY_TOKEN= # Token you set in the Meta App dashboard
11
  WHATSAPP_APP_SECRET= # App Secret from Meta App Settings > Basic
12
  WHATSAPP_ACCESS_TOKEN= # Permanent System User token from Meta Business
13
+ WHATSAPP_PHONE_NUMBER_ID= # Phone Number ID from Meta App > WhatsApp > Getting Started
14
 
15
  # ─── Database ──────────────────────────────────────────────────────────────────
16
  DATABASE_URL=postgresql://user:password@localhost:5432/edtech?schema=public
 
31
  # ─── OpenAI / AI ───────────────────────────────────────────────────────────────
32
  OPENAI_API_KEY= # sk-...
33
 
34
+ # ─── Cloudflare R2 Storage ────────────────────────────────────────────────────
35
+ R2_ACCOUNT_ID= # Cloudflare Account ID
36
+ R2_ACCESS_KEY_ID= # R2 API token Access Key ID
37
+ R2_SECRET_ACCESS_KEY= # R2 API token Secret Access Key
38
+ R2_BUCKET= # R2 bucket name (e.g. edtech-docs)
39
+ R2_PUBLIC_URL= # Public URL of the bucket (e.g. https://pub-xxx.r2.dev)
40
+
41
  # ─── Frontend ──────────────────────────────────────────────────────────────────
42
  VITE_CLIENT_URL=https://your-frontend.netlify.app
43
  VITE_WHATSAPP_NUMBER=221771234567 # Without + prefix, for wa.me links
apps/admin/src/App.tsx CHANGED
@@ -1,6 +1,110 @@
1
- import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
 
2
 
3
- import { useEffect, useState } from 'react';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  import { Users, PlayCircle, CheckCircle, Lightbulb, Download } from 'lucide-react'; interface DashboardData {
5
  stats: {
6
  totalUsers: number;
@@ -12,6 +116,7 @@ import { Users, PlayCircle, CheckCircle, Lightbulb, Download } from 'lucide-reac
12
  }
13
 
14
  function Dashboard() {
 
15
  const [data, setData] = useState<DashboardData>({ stats: null, enrollments: [] });
16
  const [loading, setLoading] = useState(true);
17
 
@@ -19,12 +124,18 @@ function Dashboard() {
19
  const fetchData = async () => {
20
  try {
21
  const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:3001';
 
22
 
23
  const [statsRes, enrollmentsRes] = await Promise.all([
24
- fetch(`${API_URL}/v1/admin/stats`),
25
- fetch(`${API_URL}/v1/admin/enrollments`)
26
  ]);
27
 
 
 
 
 
 
28
  const stats = await statsRes.json();
29
  const enrollments = await enrollmentsRes.json();
30
 
@@ -37,9 +148,9 @@ function Dashboard() {
37
  };
38
 
39
  fetchData();
40
- }, []);
41
 
42
- if (loading) return <div className="p-8">Loading dashboard...</div>;
43
 
44
  const exportCSV = () => {
45
  if (!data.enrollments || data.enrollments.length === 0) {
@@ -163,29 +274,47 @@ function Settings() {
163
  );
164
  }
165
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
  function App() {
167
  return (
168
- <Router>
169
- <div className="min-h-screen bg-gray-50 flex">
170
- {/* Sidebar */}
171
- <aside className="w-64 bg-slate-900 text-white p-6">
172
- <div className="text-xl font-bold mb-8">EdTech Admin</div>
173
- <nav className="space-y-4">
174
- <Link to="/" className="block hover:text-gray-300">Dashboard</Link>
175
- <Link to="/settings" className="block hover:text-gray-300">Settings</Link>
176
- </nav>
177
- </aside>
178
-
179
- {/* Main Content */}
180
- <main className="flex-1">
181
- <Routes>
182
- <Route path="/" element={<Dashboard />} />
183
- <Route path="/settings" element={<Settings />} />
184
- </Routes>
185
- </main>
186
- </div>
187
- </Router>
188
- )
189
  }
190
 
191
  export default App
 
1
+ import { BrowserRouter as Router, Routes, Route, Link, Navigate, useNavigate } from 'react-router-dom';
2
+ import { useEffect, useState, createContext, useContext } from 'react';
3
 
4
+ // ── Auth Context ────────────────────────────────────────────────────────────────
5
+ const SESSION_KEY = 'edtech_admin_key';
6
+
7
+ const AuthContext = createContext<{
8
+ apiKey: string | null;
9
+ login: (key: string) => void;
10
+ logout: () => void;
11
+ }>({
12
+ apiKey: null,
13
+ login: () => { },
14
+ logout: () => { },
15
+ });
16
+
17
+ function AuthProvider({ children }: { children: React.ReactNode }) {
18
+ const [apiKey, setApiKey] = useState<string | null>(
19
+ () => sessionStorage.getItem(SESSION_KEY)
20
+ );
21
+
22
+ const login = (key: string) => {
23
+ sessionStorage.setItem(SESSION_KEY, key);
24
+ setApiKey(key);
25
+ };
26
+
27
+ const logout = () => {
28
+ sessionStorage.removeItem(SESSION_KEY);
29
+ setApiKey(null);
30
+ };
31
+
32
+ return <AuthContext.Provider value={{ apiKey, login, logout }}>{children}</AuthContext.Provider>;
33
+ }
34
+
35
+ const useAuth = () => useContext(AuthContext);
36
+
37
+ function ProtectedRoute({ children }: { children: React.ReactNode }) {
38
+ const { apiKey } = useAuth();
39
+ if (!apiKey) return <Navigate to="/login" replace />;
40
+ return <>{children}</>;
41
+ }
42
+
43
+ // ── Login Page ──────────────────────────────────────────────────────────────────
44
+ function LoginPage() {
45
+ const { login, apiKey } = useAuth();
46
+ const navigate = useNavigate();
47
+ const [key, setKey] = useState('');
48
+ const [error, setError] = useState('');
49
+ const [loading, setLoading] = useState(false);
50
+
51
+ useEffect(() => {
52
+ if (apiKey) navigate('/', { replace: true });
53
+ }, [apiKey, navigate]);
54
+
55
+ const handleSubmit = async (e: React.FormEvent) => {
56
+ e.preventDefault();
57
+ setError('');
58
+ setLoading(true);
59
+ try {
60
+ const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:3001';
61
+ const res = await fetch(`${API_URL}/v1/admin/stats`, {
62
+ headers: { 'Authorization': `Bearer ${key}` }
63
+ });
64
+ if (res.ok) {
65
+ login(key);
66
+ navigate('/', { replace: true });
67
+ } else {
68
+ setError('Clé API invalide. Vérifie ton ADMIN_API_KEY.');
69
+ }
70
+ } catch {
71
+ setError('Impossible de joindre le serveur.');
72
+ } finally {
73
+ setLoading(false);
74
+ }
75
+ };
76
+
77
+ return (
78
+ <div className="min-h-screen bg-slate-900 flex items-center justify-center p-4">
79
+ <div className="bg-white rounded-2xl shadow-2xl p-8 w-full max-w-sm">
80
+ <div className="text-center mb-6">
81
+ <div className="text-3xl mb-2">🔐</div>
82
+ <h1 className="text-2xl font-bold text-slate-800">Admin Access</h1>
83
+ <p className="text-sm text-slate-500 mt-1">Entrez votre ADMIN_API_KEY</p>
84
+ </div>
85
+ <form onSubmit={handleSubmit} className="space-y-4">
86
+ <input
87
+ id="apiKey"
88
+ type="password"
89
+ required
90
+ placeholder="sk-admin-..."
91
+ value={key}
92
+ onChange={e => setKey(e.target.value)}
93
+ className="w-full border border-slate-200 rounded-xl px-4 py-3 text-sm outline-none focus:ring-2 focus:ring-slate-400 transition"
94
+ />
95
+ {error && <p className="text-red-500 text-sm">{error}</p>}
96
+ <button
97
+ type="submit"
98
+ disabled={loading}
99
+ className="w-full bg-slate-900 hover:bg-slate-700 text-white py-3 rounded-xl font-bold text-sm transition disabled:opacity-50"
100
+ >
101
+ {loading ? 'Vérification...' : 'Se connecter'}
102
+ </button>
103
+ </form>
104
+ </div>
105
+ </div>
106
+ );
107
+ }
108
  import { Users, PlayCircle, CheckCircle, Lightbulb, Download } from 'lucide-react'; interface DashboardData {
109
  stats: {
110
  totalUsers: number;
 
116
  }
117
 
118
  function Dashboard() {
119
+ const { apiKey, logout } = useAuth();
120
  const [data, setData] = useState<DashboardData>({ stats: null, enrollments: [] });
121
  const [loading, setLoading] = useState(true);
122
 
 
124
  const fetchData = async () => {
125
  try {
126
  const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:3001';
127
+ const headers = { 'Authorization': `Bearer ${apiKey}` };
128
 
129
  const [statsRes, enrollmentsRes] = await Promise.all([
130
+ fetch(`${API_URL}/v1/admin/stats`, { headers }),
131
+ fetch(`${API_URL}/v1/admin/enrollments`, { headers })
132
  ]);
133
 
134
+ if (statsRes.status === 401 || enrollmentsRes.status === 401) {
135
+ logout();
136
+ return;
137
+ }
138
+
139
  const stats = await statsRes.json();
140
  const enrollments = await enrollmentsRes.json();
141
 
 
148
  };
149
 
150
  fetchData();
151
+ }, [apiKey, logout]);
152
 
153
+ if (loading) return <div className="p-8 text-slate-500">Chargement du dashboard...</div>;
154
 
155
  const exportCSV = () => {
156
  if (!data.enrollments || data.enrollments.length === 0) {
 
274
  );
275
  }
276
 
277
+ function AppShell() {
278
+ const { logout } = useAuth();
279
+ return (
280
+ <div className="min-h-screen bg-gray-50 flex">
281
+ {/* Sidebar */}
282
+ <aside className="w-64 bg-slate-900 text-white p-6 flex flex-col">
283
+ <div className="text-xl font-bold mb-8">EdTech Admin</div>
284
+ <nav className="space-y-4 flex-1">
285
+ <Link to="/" className="block hover:text-gray-300">Dashboard</Link>
286
+ <Link to="/settings" className="block hover:text-gray-300">Settings</Link>
287
+ </nav>
288
+ <button
289
+ onClick={logout}
290
+ className="text-sm text-slate-400 hover:text-white transition mt-4 text-left"
291
+ >
292
+ 🔓 Se déconnecter
293
+ </button>
294
+ </aside>
295
+
296
+ {/* Main Content */}
297
+ <main className="flex-1">
298
+ <Routes>
299
+ <Route path="/" element={<ProtectedRoute><Dashboard /></ProtectedRoute>} />
300
+ <Route path="/settings" element={<ProtectedRoute><Settings /></ProtectedRoute>} />
301
+ </Routes>
302
+ </main>
303
+ </div>
304
+ );
305
+ }
306
+
307
  function App() {
308
  return (
309
+ <AuthProvider>
310
+ <Router>
311
+ <Routes>
312
+ <Route path="/login" element={<LoginPage />} />
313
+ <Route path="/*" element={<AppShell />} />
314
+ </Routes>
315
+ </Router>
316
+ </AuthProvider>
317
+ );
 
 
 
 
 
 
 
 
 
 
 
 
318
  }
319
 
320
  export default App
apps/api/package.json CHANGED
@@ -8,14 +8,15 @@
8
  "start": "node dist/index.js"
9
  },
10
  "dependencies": {
 
11
  "@fastify/cors": "^8.0.0",
12
  "@fastify/rate-limit": "^9.0.0",
13
- "fastify-plugin": "^4.5.1",
14
  "@prisma/client": "^5.0.0",
15
  "@repo/database": "workspace:*",
16
  "@repo/shared-types": "workspace:*",
17
  "bullmq": "^5.1.0",
18
  "fastify": "^4.0.0",
 
19
  "ioredis": "^5.9.3",
20
  "openai": "^4.0.0",
21
  "pptxgenjs": "^3.12.0",
 
8
  "start": "node dist/index.js"
9
  },
10
  "dependencies": {
11
+ "@aws-sdk/client-s3": "^3.995.0",
12
  "@fastify/cors": "^8.0.0",
13
  "@fastify/rate-limit": "^9.0.0",
 
14
  "@prisma/client": "^5.0.0",
15
  "@repo/database": "workspace:*",
16
  "@repo/shared-types": "workspace:*",
17
  "bullmq": "^5.1.0",
18
  "fastify": "^4.0.0",
19
+ "fastify-plugin": "^4.5.1",
20
  "ioredis": "^5.9.3",
21
  "openai": "^4.0.0",
22
  "pptxgenjs": "^3.12.0",
apps/api/src/routes/ai.ts CHANGED
@@ -2,14 +2,9 @@ import { FastifyInstance } from 'fastify';
2
  import { aiService } from '../services/ai';
3
  import { PdfOnePagerRenderer } from '../services/renderers/pdf-renderer';
4
  import { PptxDeckRenderer } from '../services/renderers/pptx-renderer';
 
5
  import { z } from 'zod';
6
 
7
- const mockS3Upload = async (buffer: Buffer, filename: string): Promise<string> => {
8
- // In production, upload buffer to S3/R2 here
9
- // For MVP, return a mock URL
10
- console.log(`[MOCK UPLOAD] Mocking upload of ${filename} (${buffer.length} bytes)`);
11
- return `https://dummy-storage.com/downloads/${filename}`;
12
- };
13
 
14
  export async function aiRoutes(fastify: FastifyInstance) {
15
  const pdfRenderer = new PdfOnePagerRenderer();
@@ -29,7 +24,7 @@ export async function aiRoutes(fastify: FastifyInstance) {
29
  const pdfBuffer = await pdfRenderer.render(onePagerData);
30
 
31
  // Step 3: Upload to Storage
32
- const downloadUrl = await mockS3Upload(pdfBuffer, `onepager-${Date.now()}.pdf`);
33
 
34
  return { success: true, url: downloadUrl, data: onePagerData };
35
  });
@@ -48,7 +43,7 @@ export async function aiRoutes(fastify: FastifyInstance) {
48
  const pptxBuffer = await pptxRenderer.render(deckData);
49
 
50
  // Step 3: Upload to Storage
51
- const downloadUrl = await mockS3Upload(pptxBuffer, `deck-${Date.now()}.pptx`);
52
 
53
  return { success: true, url: downloadUrl, data: deckData };
54
  });
@@ -76,7 +71,7 @@ export async function aiRoutes(fastify: FastifyInstance) {
76
  console.log(`Generating TTS audio...`);
77
 
78
  const audioBuffer = await aiService.generateSpeech(text);
79
- const downloadUrl = await mockS3Upload(audioBuffer, `lesson-audio-${Date.now()}.mp3`);
80
 
81
  return { success: true, url: downloadUrl };
82
  });
 
2
  import { aiService } from '../services/ai';
3
  import { PdfOnePagerRenderer } from '../services/renderers/pdf-renderer';
4
  import { PptxDeckRenderer } from '../services/renderers/pptx-renderer';
5
+ import { uploadFile } from '../services/storage';
6
  import { z } from 'zod';
7
 
 
 
 
 
 
 
8
 
9
  export async function aiRoutes(fastify: FastifyInstance) {
10
  const pdfRenderer = new PdfOnePagerRenderer();
 
24
  const pdfBuffer = await pdfRenderer.render(onePagerData);
25
 
26
  // Step 3: Upload to Storage
27
+ const downloadUrl = await uploadFile(pdfBuffer, `onepager-${Date.now()}.pdf`, 'application/pdf');
28
 
29
  return { success: true, url: downloadUrl, data: onePagerData };
30
  });
 
43
  const pptxBuffer = await pptxRenderer.render(deckData);
44
 
45
  // Step 3: Upload to Storage
46
+ const downloadUrl = await uploadFile(pptxBuffer, `deck-${Date.now()}.pptx`, 'application/vnd.openxmlformats-officedocument.presentationml.presentation');
47
 
48
  return { success: true, url: downloadUrl, data: deckData };
49
  });
 
71
  console.log(`Generating TTS audio...`);
72
 
73
  const audioBuffer = await aiService.generateSpeech(text);
74
+ const downloadUrl = await uploadFile(audioBuffer, `lesson-audio-${Date.now()}.mp3`, 'audio/mpeg');
75
 
76
  return { success: true, url: downloadUrl };
77
  });
apps/api/src/services/storage.ts ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Storage Service — Cloudflare R2 (S3-compatible) with local /tmp fallback
3
+ *
4
+ * Required env vars for R2 mode:
5
+ * R2_ACCOUNT_ID, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_BUCKET, R2_PUBLIC_URL
6
+ *
7
+ * Falls back to saving files in /tmp in development (returns a file:// path).
8
+ */
9
+
10
+ import fs from 'fs/promises';
11
+ import path from 'path';
12
+
13
+ // ─── R2 / S3 Upload ───────────────────────────────────────────────────────────
14
+ async function uploadToR2(buffer: Buffer, filename: string, contentType: string): Promise<string> {
15
+ const accountId = process.env.R2_ACCOUNT_ID!;
16
+ const bucket = process.env.R2_BUCKET!;
17
+ const accessKeyId = process.env.R2_ACCESS_KEY_ID!;
18
+ const secretAccessKey = process.env.R2_SECRET_ACCESS_KEY!;
19
+ const publicUrl = process.env.R2_PUBLIC_URL!; // e.g. https://pub-xxx.r2.dev
20
+
21
+ // Use native fetch with AWS Signature V4 (no SDK dependency needed for simple PUT)
22
+ const { S3Client, PutObjectCommand } = await import('@aws-sdk/client-s3');
23
+
24
+ const client = new S3Client({
25
+ region: 'auto',
26
+ endpoint: `https://${accountId}.r2.cloudflarestorage.com`,
27
+ credentials: { accessKeyId, secretAccessKey },
28
+ });
29
+
30
+ await client.send(new PutObjectCommand({
31
+ Bucket: bucket,
32
+ Key: filename,
33
+ Body: buffer,
34
+ ContentType: contentType,
35
+ }));
36
+
37
+ return `${publicUrl}/${filename}`;
38
+ }
39
+
40
+ // ─── Local /tmp Fallback ──────────────────────────────────────────────────────
41
+ async function saveLocally(buffer: Buffer, filename: string): Promise<string> {
42
+ const tmpPath = path.join('/tmp', filename);
43
+ await fs.writeFile(tmpPath, buffer);
44
+ console.warn(`[Storage] R2 not configured — file saved locally to ${tmpPath}`);
45
+ return `file://${tmpPath}`;
46
+ }
47
+
48
+ // ─── Public API ───────────────────────────────────────────────────────────────
49
+ function isR2Configured(): boolean {
50
+ return !!(
51
+ process.env.R2_ACCOUNT_ID &&
52
+ process.env.R2_ACCESS_KEY_ID &&
53
+ process.env.R2_SECRET_ACCESS_KEY &&
54
+ process.env.R2_BUCKET &&
55
+ process.env.R2_PUBLIC_URL
56
+ );
57
+ }
58
+
59
+ /**
60
+ * Upload a buffer to Cloudflare R2 (or save locally in dev) and return the public URL.
61
+ * @param buffer - File contents
62
+ * @param filename - Filename with extension (e.g. "onepager-1234.pdf")
63
+ * @param contentType - MIME type (e.g. "application/pdf")
64
+ */
65
+ export async function uploadFile(buffer: Buffer, filename: string, contentType: string): Promise<string> {
66
+ if (isR2Configured()) {
67
+ return uploadToR2(buffer, filename, contentType);
68
+ }
69
+ return saveLocally(buffer, filename);
70
+ }
apps/whatsapp-worker/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
  import { Worker, Job } from 'bullmq';
2
  import dotenv from 'dotenv';
3
  import { PrismaClient } from '@prisma/client';
 
4
 
5
  dotenv.config();
6
 
@@ -25,8 +26,12 @@ const worker = new Worker('whatsapp-queue', async (job: Job) => {
25
  try {
26
  if (job.name === 'send-message') {
27
  const { userId, text } = job.data;
28
- // TODO: Call WhatsApp Cloud API to send text
29
- console.log(`[MOCK SEND] To User ${userId}: "${text}"`);
 
 
 
 
30
  }
31
  else if (job.name === 'enroll-user') {
32
  const { userId, trackId } = job.data;
@@ -53,7 +58,13 @@ const worker = new Worker('whatsapp-queue', async (job: Job) => {
53
 
54
  const checkoutData = await checkoutRes.json();
55
  if (checkoutRes.ok && checkoutData.url) {
56
- console.log(`[MOCK SEND] To User ${userId}: "This track is Premium. Please complete your payment here: ${checkoutData.url}"`);
 
 
 
 
 
 
57
  } else {
58
  console.error('[WORKER] Failed to get checkout URL', checkoutData);
59
  }
@@ -65,14 +76,15 @@ const worker = new Worker('whatsapp-queue', async (job: Job) => {
65
  const existing = await prisma.enrollment.findFirst({ where: { userId, trackId } });
66
  if (!existing) {
67
  await prisma.enrollment.create({
68
- data: {
69
- userId,
70
- trackId,
71
- status: 'ACTIVE',
72
- currentDay: 1
73
- }
74
  });
75
- console.log(`[MOCK SEND] To User ${userId}: "Welcome to ${track.title}! Day 1 starts now."`);
 
 
 
 
 
 
76
  }
77
  }
78
  }
@@ -136,10 +148,12 @@ const worker = new Worker('whatsapp-queue', async (job: Job) => {
136
  console.error('[WORKER] Failed to generate TTS:', err);
137
  }
138
 
139
- // TODO: Call WhatsApp Cloud API with finalContent and audioUrl
140
- console.log(`[MOCK SEND CONTENT] To User ${userId}: "${finalContent}"`);
141
- if (audioUrl) {
142
- console.log(`[MOCK SEND AUDIO] To User ${userId}: 🎵 ${audioUrl}`);
 
 
143
  }
144
 
145
  // Update enrollment progress
@@ -192,7 +206,25 @@ const worker = new Worker('whatsapp-queue', async (job: Job) => {
192
  console.log(`[AI DOCS READY] 📄 PDF: ${pdfData.url}`);
193
  console.log(`[AI DOCS READY] 📊 PPTX: ${pptxData.url}`);
194
 
195
- // TODO: Send these URLs back to the user via WhatsApp!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  } catch (aiError) {
197
  console.error('[WORKER] Failed to generate AI documents:', aiError);
198
  }
 
1
  import { Worker, Job } from 'bullmq';
2
  import dotenv from 'dotenv';
3
  import { PrismaClient } from '@prisma/client';
4
+ import { sendTextMessage, sendAudioMessage, sendDocumentMessage } from './whatsapp-cloud';
5
 
6
  dotenv.config();
7
 
 
26
  try {
27
  if (job.name === 'send-message') {
28
  const { userId, text } = job.data;
29
+ const user = await prisma.user.findUnique({ where: { id: userId } });
30
+ if (user?.phone) {
31
+ await sendTextMessage(user.phone, text);
32
+ } else {
33
+ console.warn(`[WORKER] User ${userId} not found or missing phone — skipping send.`);
34
+ }
35
  }
36
  else if (job.name === 'enroll-user') {
37
  const { userId, trackId } = job.data;
 
58
 
59
  const checkoutData = await checkoutRes.json();
60
  if (checkoutRes.ok && checkoutData.url) {
61
+ const user = await prisma.user.findUnique({ where: { id: userId } });
62
+ if (user?.phone) {
63
+ await sendTextMessage(
64
+ user.phone,
65
+ `💳 Cette formation est Premium. Complétez votre paiement ici :\n${checkoutData.url}`
66
+ );
67
+ }
68
  } else {
69
  console.error('[WORKER] Failed to get checkout URL', checkoutData);
70
  }
 
76
  const existing = await prisma.enrollment.findFirst({ where: { userId, trackId } });
77
  if (!existing) {
78
  await prisma.enrollment.create({
79
+ data: { userId, trackId, status: 'ACTIVE', currentDay: 1 }
 
 
 
 
 
80
  });
81
+ const user = await prisma.user.findUnique({ where: { id: userId } });
82
+ if (user?.phone) {
83
+ await sendTextMessage(
84
+ user.phone,
85
+ `🎉 Bienvenue dans *${track.title}* ! Le Jour 1 commence maintenant.`
86
+ );
87
+ }
88
  }
89
  }
90
  }
 
148
  console.error('[WORKER] Failed to generate TTS:', err);
149
  }
150
 
151
+ // Send content + optional audio via WhatsApp
152
+ if (user?.phone) {
153
+ await sendTextMessage(user.phone, finalContent);
154
+ if (audioUrl) {
155
+ await sendAudioMessage(user.phone, audioUrl);
156
+ }
157
  }
158
 
159
  // Update enrollment progress
 
206
  console.log(`[AI DOCS READY] 📄 PDF: ${pdfData.url}`);
207
  console.log(`[AI DOCS READY] 📊 PPTX: ${pptxData.url}`);
208
 
209
+ // Send documents to user via WhatsApp
210
+ if (user?.phone) {
211
+ if (pdfData.url) {
212
+ await sendDocumentMessage(
213
+ user.phone,
214
+ pdfData.url,
215
+ 'one-pager.pdf',
216
+ '📄 Votre One-Pager est prêt !'
217
+ );
218
+ }
219
+ if (pptxData.url) {
220
+ await sendDocumentMessage(
221
+ user.phone,
222
+ pptxData.url,
223
+ 'pitch-deck.pptx',
224
+ '📊 Votre Pitch Deck est prêt !'
225
+ );
226
+ }
227
+ }
228
  } catch (aiError) {
229
  console.error('[WORKER] Failed to generate AI documents:', aiError);
230
  }
apps/whatsapp-worker/src/whatsapp-cloud.ts ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * WhatsApp Cloud API Service
3
+ *
4
+ * Wraps the Meta Graph API for sending messages.
5
+ * Requires:
6
+ * - WHATSAPP_ACCESS_TOKEN (System User token from Meta Business)
7
+ * - WHATSAPP_PHONE_NUMBER_ID (Phone Number ID from Meta App dashboard)
8
+ */
9
+
10
+ const GRAPH_API_VERSION = 'v18.0';
11
+
12
+ function getBaseUrl(): string {
13
+ const phoneNumberId = process.env.WHATSAPP_PHONE_NUMBER_ID;
14
+ if (!phoneNumberId) throw new Error('[WhatsApp] WHATSAPP_PHONE_NUMBER_ID is not set');
15
+ return `https://graph.facebook.com/${GRAPH_API_VERSION}/${phoneNumberId}/messages`;
16
+ }
17
+
18
+ function getHeaders(): Record<string, string> {
19
+ const token = process.env.WHATSAPP_ACCESS_TOKEN;
20
+ if (!token) throw new Error('[WhatsApp] WHATSAPP_ACCESS_TOKEN is not set');
21
+ return {
22
+ 'Content-Type': 'application/json',
23
+ 'Authorization': `Bearer ${token}`,
24
+ };
25
+ }
26
+
27
+ /**
28
+ * Send a plain text message to a WhatsApp phone number.
29
+ * @param to - Recipient phone number in international format (e.g. "221771234567")
30
+ * @param text - Message body (supports basic WhatsApp markdown: *bold*, _italic_)
31
+ */
32
+ export async function sendTextMessage(to: string, text: string): Promise<void> {
33
+ const body = {
34
+ messaging_product: 'whatsapp',
35
+ recipient_type: 'individual',
36
+ to,
37
+ type: 'text',
38
+ text: { preview_url: false, body: text },
39
+ };
40
+
41
+ const res = await fetch(getBaseUrl(), {
42
+ method: 'POST',
43
+ headers: getHeaders(),
44
+ body: JSON.stringify(body),
45
+ });
46
+
47
+ if (!res.ok) {
48
+ const err = await res.text();
49
+ throw new Error(`[WhatsApp] sendTextMessage failed (${res.status}): ${err}`);
50
+ }
51
+
52
+ console.log(`[WhatsApp] ✅ Text message sent to ${to}`);
53
+ }
54
+
55
+ /**
56
+ * Send a document (PDF/PPTX) via a public URL as a WhatsApp document message.
57
+ * @param to - Recipient phone number
58
+ * @param fileUrl - Public URL of the document
59
+ * @param filename - Display filename (e.g. "pitch-deck.pptx")
60
+ * @param caption - Optional caption shown under the document
61
+ */
62
+ export async function sendDocumentMessage(to: string, fileUrl: string, filename: string, caption?: string): Promise<void> {
63
+ const body = {
64
+ messaging_product: 'whatsapp',
65
+ recipient_type: 'individual',
66
+ to,
67
+ type: 'document',
68
+ document: {
69
+ link: fileUrl,
70
+ filename,
71
+ ...(caption ? { caption } : {}),
72
+ },
73
+ };
74
+
75
+ const res = await fetch(getBaseUrl(), {
76
+ method: 'POST',
77
+ headers: getHeaders(),
78
+ body: JSON.stringify(body),
79
+ });
80
+
81
+ if (!res.ok) {
82
+ const err = await res.text();
83
+ throw new Error(`[WhatsApp] sendDocumentMessage failed (${res.status}): ${err}`);
84
+ }
85
+
86
+ console.log(`[WhatsApp] ✅ Document "${filename}" sent to ${to}`);
87
+ }
88
+
89
+ /**
90
+ * Send an audio message via a public URL.
91
+ * @param to - Recipient phone number
92
+ * @param audioUrl - Public URL of the audio file (MP3/OGG)
93
+ */
94
+ export async function sendAudioMessage(to: string, audioUrl: string): Promise<void> {
95
+ const body = {
96
+ messaging_product: 'whatsapp',
97
+ recipient_type: 'individual',
98
+ to,
99
+ type: 'audio',
100
+ audio: { link: audioUrl },
101
+ };
102
+
103
+ const res = await fetch(getBaseUrl(), {
104
+ method: 'POST',
105
+ headers: getHeaders(),
106
+ body: JSON.stringify(body),
107
+ });
108
+
109
+ if (!res.ok) {
110
+ const err = await res.text();
111
+ throw new Error(`[WhatsApp] sendAudioMessage failed (${res.status}): ${err}`);
112
+ }
113
+
114
+ console.log(`[WhatsApp] ✅ Audio message sent to ${to}`);
115
+ }
pnpm-lock.yaml CHANGED
@@ -66,6 +66,9 @@ importers:
66
 
67
  apps/api:
68
  dependencies:
 
 
 
69
  '@fastify/cors':
70
  specifier: ^8.0.0
71
  version: 8.5.0
@@ -242,6 +245,173 @@ packages:
242
  resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
243
  engines: {node: '>=10'}
244
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
  '@babel/code-frame@7.29.0':
246
  resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==}
247
  engines: {node: '>=6.9.0'}
@@ -842,6 +1012,222 @@ packages:
842
  cpu: [x64]
843
  os: [win32]
844
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
845
  '@tootallnate/quickjs-emscripten@0.23.0':
846
  resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==}
847
 
@@ -1036,6 +1422,9 @@ packages:
1036
  resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
1037
  engines: {node: '>=8'}
1038
 
 
 
 
1039
  brace-expansion@2.0.2:
1040
  resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==}
1041
 
@@ -1291,6 +1680,10 @@ packages:
1291
  fast-uri@3.1.0:
1292
  resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==}
1293
 
 
 
 
 
1294
  fastify-plugin@4.5.1:
1295
  resolution: {integrity: sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==}
1296
 
@@ -2013,6 +2406,9 @@ packages:
2013
  '@types/node':
2014
  optional: true
2015
 
 
 
 
2016
  sucrase@3.35.1:
2017
  resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==}
2018
  engines: {node: '>=16 || 14 >=14.17'}
@@ -2233,6 +2629,499 @@ snapshots:
2233
 
2234
  '@alloc/quick-lru@5.2.0': {}
2235
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2236
  '@babel/code-frame@7.29.0':
2237
  dependencies:
2238
  '@babel/helper-validator-identifier': 7.28.5
@@ -2682,6 +3571,344 @@ snapshots:
2682
  '@rollup/rollup-win32-x64-msvc@4.57.1':
2683
  optional: true
2684
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2685
  '@tootallnate/quickjs-emscripten@0.23.0': {}
2686
 
2687
  '@types/babel__core@7.20.5':
@@ -2871,6 +4098,8 @@ snapshots:
2871
 
2872
  binary-extensions@2.3.0: {}
2873
 
 
 
2874
  brace-expansion@2.0.2:
2875
  dependencies:
2876
  balanced-match: 1.0.2
@@ -3176,6 +4405,10 @@ snapshots:
3176
 
3177
  fast-uri@3.1.0: {}
3178
 
 
 
 
 
3179
  fastify-plugin@4.5.1: {}
3180
 
3181
  fastify@4.29.1:
@@ -3945,6 +5178,8 @@ snapshots:
3945
  optionalDependencies:
3946
  '@types/node': 20.19.33
3947
 
 
 
3948
  sucrase@3.35.1:
3949
  dependencies:
3950
  '@jridgewell/gen-mapping': 0.3.13
 
66
 
67
  apps/api:
68
  dependencies:
69
+ '@aws-sdk/client-s3':
70
+ specifier: ^3.995.0
71
+ version: 3.995.0
72
  '@fastify/cors':
73
  specifier: ^8.0.0
74
  version: 8.5.0
 
245
  resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
246
  engines: {node: '>=10'}
247
 
248
+ '@aws-crypto/crc32@5.2.0':
249
+ resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==}
250
+ engines: {node: '>=16.0.0'}
251
+
252
+ '@aws-crypto/crc32c@5.2.0':
253
+ resolution: {integrity: sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==}
254
+
255
+ '@aws-crypto/sha1-browser@5.2.0':
256
+ resolution: {integrity: sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==}
257
+
258
+ '@aws-crypto/sha256-browser@5.2.0':
259
+ resolution: {integrity: sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==}
260
+
261
+ '@aws-crypto/sha256-js@5.2.0':
262
+ resolution: {integrity: sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==}
263
+ engines: {node: '>=16.0.0'}
264
+
265
+ '@aws-crypto/supports-web-crypto@5.2.0':
266
+ resolution: {integrity: sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==}
267
+
268
+ '@aws-crypto/util@5.2.0':
269
+ resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==}
270
+
271
+ '@aws-sdk/client-s3@3.995.0':
272
+ resolution: {integrity: sha512-r+t8qrQ0m9zoovYOH+wilp/glFRB/E+blsDyWzq2C+9qmyhCAQwaxjLaHM8T/uluAmhtZQIYqOH9ILRnvWtRNw==}
273
+ engines: {node: '>=20.0.0'}
274
+
275
+ '@aws-sdk/client-sso@3.993.0':
276
+ resolution: {integrity: sha512-VLUN+wIeNX24fg12SCbzTUBnBENlL014yMKZvRhPkcn4wHR6LKgNrjsG3fZ03Xs0XoKaGtNFi1VVrq666sGBoQ==}
277
+ engines: {node: '>=20.0.0'}
278
+
279
+ '@aws-sdk/core@3.973.11':
280
+ resolution: {integrity: sha512-wdQ8vrvHkKIV7yNUKXyjPWKCdYEUrZTHJ8Ojd5uJxXp9vqPCkUR1dpi1NtOLcrDgueJH7MUH5lQZxshjFPSbDA==}
281
+ engines: {node: '>=20.0.0'}
282
+
283
+ '@aws-sdk/crc64-nvme@3.972.0':
284
+ resolution: {integrity: sha512-ThlLhTqX68jvoIVv+pryOdb5coP1cX1/MaTbB9xkGDCbWbsqQcLqzPxuSoW1DCnAAIacmXCWpzUNOB9pv+xXQw==}
285
+ engines: {node: '>=20.0.0'}
286
+
287
+ '@aws-sdk/credential-provider-env@3.972.9':
288
+ resolution: {integrity: sha512-ZptrOwQynfupubvcngLkbdIq/aXvl/czdpEG8XJ8mN8Nb19BR0jaK0bR+tfuMU36Ez9q4xv7GGkHFqEEP2hUUQ==}
289
+ engines: {node: '>=20.0.0'}
290
+
291
+ '@aws-sdk/credential-provider-http@3.972.11':
292
+ resolution: {integrity: sha512-hECWoOoH386bGr89NQc9vA/abkGf5TJrMREt+lhNcnSNmoBS04fK7vc3LrJBSQAUGGVj0Tz3f4dHB3w5veovig==}
293
+ engines: {node: '>=20.0.0'}
294
+
295
+ '@aws-sdk/credential-provider-ini@3.972.9':
296
+ resolution: {integrity: sha512-zr1csEu9n4eDiHMTYJabX1mDGuGLgjgUnNckIivvk43DocJC9/f6DefFrnUPZXE+GHtbW50YuXb+JIxKykU74A==}
297
+ engines: {node: '>=20.0.0'}
298
+
299
+ '@aws-sdk/credential-provider-login@3.972.9':
300
+ resolution: {integrity: sha512-m4RIpVgZChv0vWS/HKChg1xLgZPpx8Z+ly9Fv7FwA8SOfuC6I3htcSaBz2Ch4bneRIiBUhwP4ziUo0UZgtJStQ==}
301
+ engines: {node: '>=20.0.0'}
302
+
303
+ '@aws-sdk/credential-provider-node@3.972.10':
304
+ resolution: {integrity: sha512-70nCESlvnzjo4LjJ8By8MYIiBogkYPSXl3WmMZfH9RZcB/Nt9qVWbFpYj6Fk1vLa4Vk8qagFVeXgxdieMxG1QA==}
305
+ engines: {node: '>=20.0.0'}
306
+
307
+ '@aws-sdk/credential-provider-process@3.972.9':
308
+ resolution: {integrity: sha512-gOWl0Fe2gETj5Bk151+LYKpeGi2lBDLNu+NMNpHRlIrKHdBmVun8/AalwMK8ci4uRfG5a3/+zvZBMpuen1SZ0A==}
309
+ engines: {node: '>=20.0.0'}
310
+
311
+ '@aws-sdk/credential-provider-sso@3.972.9':
312
+ resolution: {integrity: sha512-ey7S686foGTArvFhi3ifQXmgptKYvLSGE2250BAQceMSXZddz7sUSNERGJT2S7u5KIe/kgugxrt01hntXVln6w==}
313
+ engines: {node: '>=20.0.0'}
314
+
315
+ '@aws-sdk/credential-provider-web-identity@3.972.9':
316
+ resolution: {integrity: sha512-8LnfS76nHXoEc9aRRiMMpxZxJeDG0yusdyo3NvPhCgESmBUgpMa4luhGbClW5NoX/qRcGxxM6Z/esqANSNMTow==}
317
+ engines: {node: '>=20.0.0'}
318
+
319
+ '@aws-sdk/middleware-bucket-endpoint@3.972.3':
320
+ resolution: {integrity: sha512-fmbgWYirF67YF1GfD7cg5N6HHQ96EyRNx/rDIrTF277/zTWVuPI2qS/ZHgofwR1NZPe/NWvoppflQY01LrbVLg==}
321
+ engines: {node: '>=20.0.0'}
322
+
323
+ '@aws-sdk/middleware-expect-continue@3.972.3':
324
+ resolution: {integrity: sha512-4msC33RZsXQpUKR5QR4HnvBSNCPLGHmB55oDiROqqgyOc+TOfVu2xgi5goA7ms6MdZLeEh2905UfWMnMMF4mRg==}
325
+ engines: {node: '>=20.0.0'}
326
+
327
+ '@aws-sdk/middleware-flexible-checksums@3.972.9':
328
+ resolution: {integrity: sha512-E663+r/UQpvF3aJkD40p5ZANVQFsUcbE39jifMtN7wc0t1M0+2gJJp3i75R49aY9OiSX5lfVyPUNjN/BNRCCZA==}
329
+ engines: {node: '>=20.0.0'}
330
+
331
+ '@aws-sdk/middleware-host-header@3.972.3':
332
+ resolution: {integrity: sha512-aknPTb2M+G3s+0qLCx4Li/qGZH8IIYjugHMv15JTYMe6mgZO8VBpYgeGYsNMGCqCZOcWzuf900jFBG5bopfzmA==}
333
+ engines: {node: '>=20.0.0'}
334
+
335
+ '@aws-sdk/middleware-location-constraint@3.972.3':
336
+ resolution: {integrity: sha512-nIg64CVrsXp67vbK0U1/Is8rik3huS3QkRHn2DRDx4NldrEFMgdkZGI/+cZMKD9k4YOS110Dfu21KZLHrFA/1g==}
337
+ engines: {node: '>=20.0.0'}
338
+
339
+ '@aws-sdk/middleware-logger@3.972.3':
340
+ resolution: {integrity: sha512-Ftg09xNNRqaz9QNzlfdQWfpqMCJbsQdnZVJP55jfhbKi1+FTWxGuvfPoBhDHIovqWKjqbuiew3HuhxbJ0+OjgA==}
341
+ engines: {node: '>=20.0.0'}
342
+
343
+ '@aws-sdk/middleware-recursion-detection@3.972.3':
344
+ resolution: {integrity: sha512-PY57QhzNuXHnwbJgbWYTrqIDHYSeOlhfYERTAuc16LKZpTZRJUjzBFokp9hF7u1fuGeE3D70ERXzdbMBOqQz7Q==}
345
+ engines: {node: '>=20.0.0'}
346
+
347
+ '@aws-sdk/middleware-sdk-s3@3.972.11':
348
+ resolution: {integrity: sha512-Qr0T7ZQTRMOuR6ahxEoJR1thPVovfWrKB2a6KBGR+a8/ELrFodrgHwhq50n+5VMaGuLtGhHiISU3XGsZmtmVXQ==}
349
+ engines: {node: '>=20.0.0'}
350
+
351
+ '@aws-sdk/middleware-ssec@3.972.3':
352
+ resolution: {integrity: sha512-dU6kDuULN3o3jEHcjm0c4zWJlY1zWVkjG9NPe9qxYLLpcbdj5kRYBS2DdWYD+1B9f910DezRuws7xDEqKkHQIg==}
353
+ engines: {node: '>=20.0.0'}
354
+
355
+ '@aws-sdk/middleware-user-agent@3.972.11':
356
+ resolution: {integrity: sha512-R8CvPsPHXwzIHCAza+bllY6PrctEk4lYq/SkHJz9NLoBHCcKQrbOcsfXxO6xmipSbUNIbNIUhH0lBsJGgsRdiw==}
357
+ engines: {node: '>=20.0.0'}
358
+
359
+ '@aws-sdk/nested-clients@3.993.0':
360
+ resolution: {integrity: sha512-iOq86f2H67924kQUIPOAvlmMaOAvOLoDOIb66I2YqSUpMYB6ufiuJW3RlREgskxv86S5qKzMnfy/X6CqMjK6XQ==}
361
+ engines: {node: '>=20.0.0'}
362
+
363
+ '@aws-sdk/region-config-resolver@3.972.3':
364
+ resolution: {integrity: sha512-v4J8qYAWfOMcZ4MJUyatntOicTzEMaU7j3OpkRCGGFSL2NgXQ5VbxauIyORA+pxdKZ0qQG2tCQjQjZDlXEC3Ow==}
365
+ engines: {node: '>=20.0.0'}
366
+
367
+ '@aws-sdk/signature-v4-multi-region@3.995.0':
368
+ resolution: {integrity: sha512-9Qx5JcAucnxnomREPb2D6L8K8GLG0rknt3+VK/BU3qTUynAcV4W21DQ04Z2RKDw+DYpW88lsZpXbVetWST2WUg==}
369
+ engines: {node: '>=20.0.0'}
370
+
371
+ '@aws-sdk/token-providers@3.993.0':
372
+ resolution: {integrity: sha512-+35g4c+8r7sB9Sjp1KPdM8qxGn6B/shBjJtEUN4e+Edw9UEQlZKIzioOGu3UAbyE0a/s450LdLZr4wbJChtmww==}
373
+ engines: {node: '>=20.0.0'}
374
+
375
+ '@aws-sdk/types@3.973.1':
376
+ resolution: {integrity: sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg==}
377
+ engines: {node: '>=20.0.0'}
378
+
379
+ '@aws-sdk/util-arn-parser@3.972.2':
380
+ resolution: {integrity: sha512-VkykWbqMjlSgBFDyrY3nOSqupMc6ivXuGmvci6Q3NnLq5kC+mKQe2QBZ4nrWRE/jqOxeFP2uYzLtwncYYcvQDg==}
381
+ engines: {node: '>=20.0.0'}
382
+
383
+ '@aws-sdk/util-endpoints@3.993.0':
384
+ resolution: {integrity: sha512-j6vioBeRZ4eHX4SWGvGPpwGg/xSOcK7f1GL0VM+rdf3ZFTIsUEhCFmD78B+5r2PgztcECSzEfvHQX01k8dPQPw==}
385
+ engines: {node: '>=20.0.0'}
386
+
387
+ '@aws-sdk/util-endpoints@3.995.0':
388
+ resolution: {integrity: sha512-aym/pjB8SLbo9w2nmkrDdAAVKVlf7CM71B9mKhjDbJTzwpSFBPHqJIMdDyj0mLumKC0aIVDr1H6U+59m9GvMFw==}
389
+ engines: {node: '>=20.0.0'}
390
+
391
+ '@aws-sdk/util-locate-window@3.965.4':
392
+ resolution: {integrity: sha512-H1onv5SkgPBK2P6JR2MjGgbOnttoNzSPIRoeZTNPZYyaplwGg50zS3amXvXqF0/qfXpWEC9rLWU564QTB9bSog==}
393
+ engines: {node: '>=20.0.0'}
394
+
395
+ '@aws-sdk/util-user-agent-browser@3.972.3':
396
+ resolution: {integrity: sha512-JurOwkRUcXD/5MTDBcqdyQ9eVedtAsZgw5rBwktsPTN7QtPiS2Ld1jkJepNgYoCufz1Wcut9iup7GJDoIHp8Fw==}
397
+
398
+ '@aws-sdk/util-user-agent-node@3.972.10':
399
+ resolution: {integrity: sha512-LVXzICPlsheET+sE6tkcS47Q5HkSTrANIlqL1iFxGAY/wRQ236DX/PCAK56qMh9QJoXAfXfoRW0B0Og4R+X7Nw==}
400
+ engines: {node: '>=20.0.0'}
401
+ peerDependencies:
402
+ aws-crt: '>=1.0.0'
403
+ peerDependenciesMeta:
404
+ aws-crt:
405
+ optional: true
406
+
407
+ '@aws-sdk/xml-builder@3.972.5':
408
+ resolution: {integrity: sha512-mCae5Ys6Qm1LDu0qdGwx2UQ63ONUe+FHw908fJzLDqFKTDBK4LDZUqKWm4OkTCNFq19bftjsBSESIGLD/s3/rA==}
409
+ engines: {node: '>=20.0.0'}
410
+
411
+ '@aws/lambda-invoke-store@0.2.3':
412
+ resolution: {integrity: sha512-oLvsaPMTBejkkmHhjf09xTgk71mOqyr/409NKhRIL08If7AhVfUsJhVsx386uJaqNd42v9kWamQ9lFbkoC2dYw==}
413
+ engines: {node: '>=18.0.0'}
414
+
415
  '@babel/code-frame@7.29.0':
416
  resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==}
417
  engines: {node: '>=6.9.0'}
 
1012
  cpu: [x64]
1013
  os: [win32]
1014
 
1015
+ '@smithy/abort-controller@4.2.8':
1016
+ resolution: {integrity: sha512-peuVfkYHAmS5ybKxWcfraK7WBBP0J+rkfUcbHJJKQ4ir3UAUNQI+Y4Vt/PqSzGqgloJ5O1dk7+WzNL8wcCSXbw==}
1017
+ engines: {node: '>=18.0.0'}
1018
+
1019
+ '@smithy/chunked-blob-reader-native@4.2.1':
1020
+ resolution: {integrity: sha512-lX9Ay+6LisTfpLid2zZtIhSEjHMZoAR5hHCR4H7tBz/Zkfr5ea8RcQ7Tk4mi0P76p4cN+Btz16Ffno7YHpKXnQ==}
1021
+ engines: {node: '>=18.0.0'}
1022
+
1023
+ '@smithy/chunked-blob-reader@5.2.0':
1024
+ resolution: {integrity: sha512-WmU0TnhEAJLWvfSeMxBNe5xtbselEO8+4wG0NtZeL8oR21WgH1xiO37El+/Y+H/Ie4SCwBy3MxYWmOYaGgZueA==}
1025
+ engines: {node: '>=18.0.0'}
1026
+
1027
+ '@smithy/config-resolver@4.4.6':
1028
+ resolution: {integrity: sha512-qJpzYC64kaj3S0fueiu3kXm8xPrR3PcXDPEgnaNMRn0EjNSZFoFjvbUp0YUDsRhN1CB90EnHJtbxWKevnH99UQ==}
1029
+ engines: {node: '>=18.0.0'}
1030
+
1031
+ '@smithy/core@3.23.2':
1032
+ resolution: {integrity: sha512-HaaH4VbGie4t0+9nY3tNBRSxVTr96wzIqexUa6C2qx3MPePAuz7lIxPxYtt1Wc//SPfJLNoZJzfdt0B6ksj2jA==}
1033
+ engines: {node: '>=18.0.0'}
1034
+
1035
+ '@smithy/credential-provider-imds@4.2.8':
1036
+ resolution: {integrity: sha512-FNT0xHS1c/CPN8upqbMFP83+ul5YgdisfCfkZ86Jh2NSmnqw/AJ6x5pEogVCTVvSm7j9MopRU89bmDelxuDMYw==}
1037
+ engines: {node: '>=18.0.0'}
1038
+
1039
+ '@smithy/eventstream-codec@4.2.8':
1040
+ resolution: {integrity: sha512-jS/O5Q14UsufqoGhov7dHLOPCzkYJl9QDzusI2Psh4wyYx/izhzvX9P4D69aTxcdfVhEPhjK+wYyn/PzLjKbbw==}
1041
+ engines: {node: '>=18.0.0'}
1042
+
1043
+ '@smithy/eventstream-serde-browser@4.2.8':
1044
+ resolution: {integrity: sha512-MTfQT/CRQz5g24ayXdjg53V0mhucZth4PESoA5IhvaWVDTOQLfo8qI9vzqHcPsdd2v6sqfTYqF5L/l+pea5Uyw==}
1045
+ engines: {node: '>=18.0.0'}
1046
+
1047
+ '@smithy/eventstream-serde-config-resolver@4.3.8':
1048
+ resolution: {integrity: sha512-ah12+luBiDGzBruhu3efNy1IlbwSEdNiw8fOZksoKoWW1ZHvO/04MQsdnws/9Aj+5b0YXSSN2JXKy/ClIsW8MQ==}
1049
+ engines: {node: '>=18.0.0'}
1050
+
1051
+ '@smithy/eventstream-serde-node@4.2.8':
1052
+ resolution: {integrity: sha512-cYpCpp29z6EJHa5T9WL0KAlq3SOKUQkcgSoeRfRVwjGgSFl7Uh32eYGt7IDYCX20skiEdRffyDpvF2efEZPC0A==}
1053
+ engines: {node: '>=18.0.0'}
1054
+
1055
+ '@smithy/eventstream-serde-universal@4.2.8':
1056
+ resolution: {integrity: sha512-iJ6YNJd0bntJYnX6s52NC4WFYcZeKrPUr1Kmmr5AwZcwCSzVpS7oavAmxMR7pMq7V+D1G4s9F5NJK0xwOsKAlQ==}
1057
+ engines: {node: '>=18.0.0'}
1058
+
1059
+ '@smithy/fetch-http-handler@5.3.9':
1060
+ resolution: {integrity: sha512-I4UhmcTYXBrct03rwzQX1Y/iqQlzVQaPxWjCjula++5EmWq9YGBrx6bbGqluGc1f0XEfhSkiY4jhLgbsJUMKRA==}
1061
+ engines: {node: '>=18.0.0'}
1062
+
1063
+ '@smithy/hash-blob-browser@4.2.9':
1064
+ resolution: {integrity: sha512-m80d/iicI7DlBDxyQP6Th7BW/ejDGiF0bgI754+tiwK0lgMkcaIBgvwwVc7OFbY4eUzpGtnig52MhPAEJ7iNYg==}
1065
+ engines: {node: '>=18.0.0'}
1066
+
1067
+ '@smithy/hash-node@4.2.8':
1068
+ resolution: {integrity: sha512-7ZIlPbmaDGxVoxErDZnuFG18WekhbA/g2/i97wGj+wUBeS6pcUeAym8u4BXh/75RXWhgIJhyC11hBzig6MljwA==}
1069
+ engines: {node: '>=18.0.0'}
1070
+
1071
+ '@smithy/hash-stream-node@4.2.8':
1072
+ resolution: {integrity: sha512-v0FLTXgHrTeheYZFGhR+ehX5qUm4IQsjAiL9qehad2cyjMWcN2QG6/4mSwbSgEQzI7jwfoXj7z4fxZUx/Mhj2w==}
1073
+ engines: {node: '>=18.0.0'}
1074
+
1075
+ '@smithy/invalid-dependency@4.2.8':
1076
+ resolution: {integrity: sha512-N9iozRybwAQ2dn9Fot9kI6/w9vos2oTXLhtK7ovGqwZjlOcxu6XhPlpLpC+INsxktqHinn5gS2DXDjDF2kG5sQ==}
1077
+ engines: {node: '>=18.0.0'}
1078
+
1079
+ '@smithy/is-array-buffer@2.2.0':
1080
+ resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==}
1081
+ engines: {node: '>=14.0.0'}
1082
+
1083
+ '@smithy/is-array-buffer@4.2.0':
1084
+ resolution: {integrity: sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==}
1085
+ engines: {node: '>=18.0.0'}
1086
+
1087
+ '@smithy/md5-js@4.2.8':
1088
+ resolution: {integrity: sha512-oGMaLj4tVZzLi3itBa9TCswgMBr7k9b+qKYowQ6x1rTyTuO1IU2YHdHUa+891OsOH+wCsH7aTPRsTJO3RMQmjQ==}
1089
+ engines: {node: '>=18.0.0'}
1090
+
1091
+ '@smithy/middleware-content-length@4.2.8':
1092
+ resolution: {integrity: sha512-RO0jeoaYAB1qBRhfVyq0pMgBoUK34YEJxVxyjOWYZiOKOq2yMZ4MnVXMZCUDenpozHue207+9P5ilTV1zeda0A==}
1093
+ engines: {node: '>=18.0.0'}
1094
+
1095
+ '@smithy/middleware-endpoint@4.4.16':
1096
+ resolution: {integrity: sha512-L5GICFCSsNhbJ5JSKeWFGFy16Q2OhoBizb3X2DrxaJwXSEujVvjG9Jt386dpQn2t7jINglQl0b4K/Su69BdbMA==}
1097
+ engines: {node: '>=18.0.0'}
1098
+
1099
+ '@smithy/middleware-retry@4.4.33':
1100
+ resolution: {integrity: sha512-jLqZOdJhtIL4lnA9hXnAG6GgnJlo1sD3FqsTxm9wSfjviqgWesY/TMBVnT84yr4O0Vfe0jWoXlfFbzsBVph3WA==}
1101
+ engines: {node: '>=18.0.0'}
1102
+
1103
+ '@smithy/middleware-serde@4.2.9':
1104
+ resolution: {integrity: sha512-eMNiej0u/snzDvlqRGSN3Vl0ESn3838+nKyVfF2FKNXFbi4SERYT6PR392D39iczngbqqGG0Jl1DlCnp7tBbXQ==}
1105
+ engines: {node: '>=18.0.0'}
1106
+
1107
+ '@smithy/middleware-stack@4.2.8':
1108
+ resolution: {integrity: sha512-w6LCfOviTYQjBctOKSwy6A8FIkQy7ICvglrZFl6Bw4FmcQ1Z420fUtIhxaUZZshRe0VCq4kvDiPiXrPZAe8oRA==}
1109
+ engines: {node: '>=18.0.0'}
1110
+
1111
+ '@smithy/node-config-provider@4.3.8':
1112
+ resolution: {integrity: sha512-aFP1ai4lrbVlWjfpAfRSL8KFcnJQYfTl5QxLJXY32vghJrDuFyPZ6LtUL+JEGYiFRG1PfPLHLoxj107ulncLIg==}
1113
+ engines: {node: '>=18.0.0'}
1114
+
1115
+ '@smithy/node-http-handler@4.4.10':
1116
+ resolution: {integrity: sha512-u4YeUwOWRZaHbWaebvrs3UhwQwj+2VNmcVCwXcYTvPIuVyM7Ex1ftAj+fdbG/P4AkBwLq/+SKn+ydOI4ZJE9PA==}
1117
+ engines: {node: '>=18.0.0'}
1118
+
1119
+ '@smithy/property-provider@4.2.8':
1120
+ resolution: {integrity: sha512-EtCTbyIveCKeOXDSWSdze3k612yCPq1YbXsbqX3UHhkOSW8zKsM9NOJG5gTIya0vbY2DIaieG8pKo1rITHYL0w==}
1121
+ engines: {node: '>=18.0.0'}
1122
+
1123
+ '@smithy/protocol-http@5.3.8':
1124
+ resolution: {integrity: sha512-QNINVDhxpZ5QnP3aviNHQFlRogQZDfYlCkQT+7tJnErPQbDhysondEjhikuANxgMsZrkGeiAxXy4jguEGsDrWQ==}
1125
+ engines: {node: '>=18.0.0'}
1126
+
1127
+ '@smithy/querystring-builder@4.2.8':
1128
+ resolution: {integrity: sha512-Xr83r31+DrE8CP3MqPgMJl+pQlLLmOfiEUnoyAlGzzJIrEsbKsPy1hqH0qySaQm4oWrCBlUqRt+idEgunKB+iw==}
1129
+ engines: {node: '>=18.0.0'}
1130
+
1131
+ '@smithy/querystring-parser@4.2.8':
1132
+ resolution: {integrity: sha512-vUurovluVy50CUlazOiXkPq40KGvGWSdmusa3130MwrR1UNnNgKAlj58wlOe61XSHRpUfIIh6cE0zZ8mzKaDPA==}
1133
+ engines: {node: '>=18.0.0'}
1134
+
1135
+ '@smithy/service-error-classification@4.2.8':
1136
+ resolution: {integrity: sha512-mZ5xddodpJhEt3RkCjbmUQuXUOaPNTkbMGR0bcS8FE0bJDLMZlhmpgrvPNCYglVw5rsYTpSnv19womw9WWXKQQ==}
1137
+ engines: {node: '>=18.0.0'}
1138
+
1139
+ '@smithy/shared-ini-file-loader@4.4.3':
1140
+ resolution: {integrity: sha512-DfQjxXQnzC5UbCUPeC3Ie8u+rIWZTvuDPAGU/BxzrOGhRvgUanaP68kDZA+jaT3ZI+djOf+4dERGlm9mWfFDrg==}
1141
+ engines: {node: '>=18.0.0'}
1142
+
1143
+ '@smithy/signature-v4@5.3.8':
1144
+ resolution: {integrity: sha512-6A4vdGj7qKNRF16UIcO8HhHjKW27thsxYci+5r/uVRkdcBEkOEiY8OMPuydLX4QHSrJqGHPJzPRwwVTqbLZJhg==}
1145
+ engines: {node: '>=18.0.0'}
1146
+
1147
+ '@smithy/smithy-client@4.11.5':
1148
+ resolution: {integrity: sha512-xixwBRqoeP2IUgcAl3U9dvJXc+qJum4lzo3maaJxifsZxKUYLfVfCXvhT4/jD01sRrHg5zjd1cw2Zmjr4/SuKQ==}
1149
+ engines: {node: '>=18.0.0'}
1150
+
1151
+ '@smithy/types@4.12.0':
1152
+ resolution: {integrity: sha512-9YcuJVTOBDjg9LWo23Qp0lTQ3D7fQsQtwle0jVfpbUHy9qBwCEgKuVH4FqFB3VYu0nwdHKiEMA+oXz7oV8X1kw==}
1153
+ engines: {node: '>=18.0.0'}
1154
+
1155
+ '@smithy/url-parser@4.2.8':
1156
+ resolution: {integrity: sha512-NQho9U68TGMEU639YkXnVMV3GEFFULmmaWdlu1E9qzyIePOHsoSnagTGSDv1Zi8DCNN6btxOSdgmy5E/hsZwhA==}
1157
+ engines: {node: '>=18.0.0'}
1158
+
1159
+ '@smithy/util-base64@4.3.0':
1160
+ resolution: {integrity: sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==}
1161
+ engines: {node: '>=18.0.0'}
1162
+
1163
+ '@smithy/util-body-length-browser@4.2.0':
1164
+ resolution: {integrity: sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==}
1165
+ engines: {node: '>=18.0.0'}
1166
+
1167
+ '@smithy/util-body-length-node@4.2.1':
1168
+ resolution: {integrity: sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==}
1169
+ engines: {node: '>=18.0.0'}
1170
+
1171
+ '@smithy/util-buffer-from@2.2.0':
1172
+ resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==}
1173
+ engines: {node: '>=14.0.0'}
1174
+
1175
+ '@smithy/util-buffer-from@4.2.0':
1176
+ resolution: {integrity: sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==}
1177
+ engines: {node: '>=18.0.0'}
1178
+
1179
+ '@smithy/util-config-provider@4.2.0':
1180
+ resolution: {integrity: sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==}
1181
+ engines: {node: '>=18.0.0'}
1182
+
1183
+ '@smithy/util-defaults-mode-browser@4.3.32':
1184
+ resolution: {integrity: sha512-092sjYfFMQ/iaPH798LY/OJFBcYu0sSK34Oy9vdixhsU36zlZu8OcYjF3TD4e2ARupyK7xaxPXl+T0VIJTEkkg==}
1185
+ engines: {node: '>=18.0.0'}
1186
+
1187
+ '@smithy/util-defaults-mode-node@4.2.35':
1188
+ resolution: {integrity: sha512-miz/ggz87M8VuM29y7jJZMYkn7+IErM5p5UgKIf8OtqVs/h2bXr1Bt3uTsREsI/4nK8a0PQERbAPsVPVNIsG7Q==}
1189
+ engines: {node: '>=18.0.0'}
1190
+
1191
+ '@smithy/util-endpoints@3.2.8':
1192
+ resolution: {integrity: sha512-8JaVTn3pBDkhZgHQ8R0epwWt+BqPSLCjdjXXusK1onwJlRuN69fbvSK66aIKKO7SwVFM6x2J2ox5X8pOaWcUEw==}
1193
+ engines: {node: '>=18.0.0'}
1194
+
1195
+ '@smithy/util-hex-encoding@4.2.0':
1196
+ resolution: {integrity: sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==}
1197
+ engines: {node: '>=18.0.0'}
1198
+
1199
+ '@smithy/util-middleware@4.2.8':
1200
+ resolution: {integrity: sha512-PMqfeJxLcNPMDgvPbbLl/2Vpin+luxqTGPpW3NAQVLbRrFRzTa4rNAASYeIGjRV9Ytuhzny39SpyU04EQreF+A==}
1201
+ engines: {node: '>=18.0.0'}
1202
+
1203
+ '@smithy/util-retry@4.2.8':
1204
+ resolution: {integrity: sha512-CfJqwvoRY0kTGe5AkQokpURNCT1u/MkRzMTASWMPPo2hNSnKtF1D45dQl3DE2LKLr4m+PW9mCeBMJr5mCAVThg==}
1205
+ engines: {node: '>=18.0.0'}
1206
+
1207
+ '@smithy/util-stream@4.5.12':
1208
+ resolution: {integrity: sha512-D8tgkrmhAX/UNeCZbqbEO3uqyghUnEmmoO9YEvRuwxjlkKKUE7FOgCJnqpTlQPe9MApdWPky58mNQQHbnCzoNg==}
1209
+ engines: {node: '>=18.0.0'}
1210
+
1211
+ '@smithy/util-uri-escape@4.2.0':
1212
+ resolution: {integrity: sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==}
1213
+ engines: {node: '>=18.0.0'}
1214
+
1215
+ '@smithy/util-utf8@2.3.0':
1216
+ resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==}
1217
+ engines: {node: '>=14.0.0'}
1218
+
1219
+ '@smithy/util-utf8@4.2.0':
1220
+ resolution: {integrity: sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==}
1221
+ engines: {node: '>=18.0.0'}
1222
+
1223
+ '@smithy/util-waiter@4.2.8':
1224
+ resolution: {integrity: sha512-n+lahlMWk+aejGuax7DPWtqav8HYnWxQwR+LCG2BgCUmaGcTe9qZCFsmw8TMg9iG75HOwhrJCX9TCJRLH+Yzqg==}
1225
+ engines: {node: '>=18.0.0'}
1226
+
1227
+ '@smithy/uuid@1.1.0':
1228
+ resolution: {integrity: sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==}
1229
+ engines: {node: '>=18.0.0'}
1230
+
1231
  '@tootallnate/quickjs-emscripten@0.23.0':
1232
  resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==}
1233
 
 
1422
  resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
1423
  engines: {node: '>=8'}
1424
 
1425
+ bowser@2.14.1:
1426
+ resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==}
1427
+
1428
  brace-expansion@2.0.2:
1429
  resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==}
1430
 
 
1680
  fast-uri@3.1.0:
1681
  resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==}
1682
 
1683
+ fast-xml-parser@5.3.6:
1684
+ resolution: {integrity: sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA==}
1685
+ hasBin: true
1686
+
1687
  fastify-plugin@4.5.1:
1688
  resolution: {integrity: sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==}
1689
 
 
2406
  '@types/node':
2407
  optional: true
2408
 
2409
+ strnum@2.1.2:
2410
+ resolution: {integrity: sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==}
2411
+
2412
  sucrase@3.35.1:
2413
  resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==}
2414
  engines: {node: '>=16 || 14 >=14.17'}
 
2629
 
2630
  '@alloc/quick-lru@5.2.0': {}
2631
 
2632
+ '@aws-crypto/crc32@5.2.0':
2633
+ dependencies:
2634
+ '@aws-crypto/util': 5.2.0
2635
+ '@aws-sdk/types': 3.973.1
2636
+ tslib: 2.8.1
2637
+
2638
+ '@aws-crypto/crc32c@5.2.0':
2639
+ dependencies:
2640
+ '@aws-crypto/util': 5.2.0
2641
+ '@aws-sdk/types': 3.973.1
2642
+ tslib: 2.8.1
2643
+
2644
+ '@aws-crypto/sha1-browser@5.2.0':
2645
+ dependencies:
2646
+ '@aws-crypto/supports-web-crypto': 5.2.0
2647
+ '@aws-crypto/util': 5.2.0
2648
+ '@aws-sdk/types': 3.973.1
2649
+ '@aws-sdk/util-locate-window': 3.965.4
2650
+ '@smithy/util-utf8': 2.3.0
2651
+ tslib: 2.8.1
2652
+
2653
+ '@aws-crypto/sha256-browser@5.2.0':
2654
+ dependencies:
2655
+ '@aws-crypto/sha256-js': 5.2.0
2656
+ '@aws-crypto/supports-web-crypto': 5.2.0
2657
+ '@aws-crypto/util': 5.2.0
2658
+ '@aws-sdk/types': 3.973.1
2659
+ '@aws-sdk/util-locate-window': 3.965.4
2660
+ '@smithy/util-utf8': 2.3.0
2661
+ tslib: 2.8.1
2662
+
2663
+ '@aws-crypto/sha256-js@5.2.0':
2664
+ dependencies:
2665
+ '@aws-crypto/util': 5.2.0
2666
+ '@aws-sdk/types': 3.973.1
2667
+ tslib: 2.8.1
2668
+
2669
+ '@aws-crypto/supports-web-crypto@5.2.0':
2670
+ dependencies:
2671
+ tslib: 2.8.1
2672
+
2673
+ '@aws-crypto/util@5.2.0':
2674
+ dependencies:
2675
+ '@aws-sdk/types': 3.973.1
2676
+ '@smithy/util-utf8': 2.3.0
2677
+ tslib: 2.8.1
2678
+
2679
+ '@aws-sdk/client-s3@3.995.0':
2680
+ dependencies:
2681
+ '@aws-crypto/sha1-browser': 5.2.0
2682
+ '@aws-crypto/sha256-browser': 5.2.0
2683
+ '@aws-crypto/sha256-js': 5.2.0
2684
+ '@aws-sdk/core': 3.973.11
2685
+ '@aws-sdk/credential-provider-node': 3.972.10
2686
+ '@aws-sdk/middleware-bucket-endpoint': 3.972.3
2687
+ '@aws-sdk/middleware-expect-continue': 3.972.3
2688
+ '@aws-sdk/middleware-flexible-checksums': 3.972.9
2689
+ '@aws-sdk/middleware-host-header': 3.972.3
2690
+ '@aws-sdk/middleware-location-constraint': 3.972.3
2691
+ '@aws-sdk/middleware-logger': 3.972.3
2692
+ '@aws-sdk/middleware-recursion-detection': 3.972.3
2693
+ '@aws-sdk/middleware-sdk-s3': 3.972.11
2694
+ '@aws-sdk/middleware-ssec': 3.972.3
2695
+ '@aws-sdk/middleware-user-agent': 3.972.11
2696
+ '@aws-sdk/region-config-resolver': 3.972.3
2697
+ '@aws-sdk/signature-v4-multi-region': 3.995.0
2698
+ '@aws-sdk/types': 3.973.1
2699
+ '@aws-sdk/util-endpoints': 3.995.0
2700
+ '@aws-sdk/util-user-agent-browser': 3.972.3
2701
+ '@aws-sdk/util-user-agent-node': 3.972.10
2702
+ '@smithy/config-resolver': 4.4.6
2703
+ '@smithy/core': 3.23.2
2704
+ '@smithy/eventstream-serde-browser': 4.2.8
2705
+ '@smithy/eventstream-serde-config-resolver': 4.3.8
2706
+ '@smithy/eventstream-serde-node': 4.2.8
2707
+ '@smithy/fetch-http-handler': 5.3.9
2708
+ '@smithy/hash-blob-browser': 4.2.9
2709
+ '@smithy/hash-node': 4.2.8
2710
+ '@smithy/hash-stream-node': 4.2.8
2711
+ '@smithy/invalid-dependency': 4.2.8
2712
+ '@smithy/md5-js': 4.2.8
2713
+ '@smithy/middleware-content-length': 4.2.8
2714
+ '@smithy/middleware-endpoint': 4.4.16
2715
+ '@smithy/middleware-retry': 4.4.33
2716
+ '@smithy/middleware-serde': 4.2.9
2717
+ '@smithy/middleware-stack': 4.2.8
2718
+ '@smithy/node-config-provider': 4.3.8
2719
+ '@smithy/node-http-handler': 4.4.10
2720
+ '@smithy/protocol-http': 5.3.8
2721
+ '@smithy/smithy-client': 4.11.5
2722
+ '@smithy/types': 4.12.0
2723
+ '@smithy/url-parser': 4.2.8
2724
+ '@smithy/util-base64': 4.3.0
2725
+ '@smithy/util-body-length-browser': 4.2.0
2726
+ '@smithy/util-body-length-node': 4.2.1
2727
+ '@smithy/util-defaults-mode-browser': 4.3.32
2728
+ '@smithy/util-defaults-mode-node': 4.2.35
2729
+ '@smithy/util-endpoints': 3.2.8
2730
+ '@smithy/util-middleware': 4.2.8
2731
+ '@smithy/util-retry': 4.2.8
2732
+ '@smithy/util-stream': 4.5.12
2733
+ '@smithy/util-utf8': 4.2.0
2734
+ '@smithy/util-waiter': 4.2.8
2735
+ tslib: 2.8.1
2736
+ transitivePeerDependencies:
2737
+ - aws-crt
2738
+
2739
+ '@aws-sdk/client-sso@3.993.0':
2740
+ dependencies:
2741
+ '@aws-crypto/sha256-browser': 5.2.0
2742
+ '@aws-crypto/sha256-js': 5.2.0
2743
+ '@aws-sdk/core': 3.973.11
2744
+ '@aws-sdk/middleware-host-header': 3.972.3
2745
+ '@aws-sdk/middleware-logger': 3.972.3
2746
+ '@aws-sdk/middleware-recursion-detection': 3.972.3
2747
+ '@aws-sdk/middleware-user-agent': 3.972.11
2748
+ '@aws-sdk/region-config-resolver': 3.972.3
2749
+ '@aws-sdk/types': 3.973.1
2750
+ '@aws-sdk/util-endpoints': 3.993.0
2751
+ '@aws-sdk/util-user-agent-browser': 3.972.3
2752
+ '@aws-sdk/util-user-agent-node': 3.972.10
2753
+ '@smithy/config-resolver': 4.4.6
2754
+ '@smithy/core': 3.23.2
2755
+ '@smithy/fetch-http-handler': 5.3.9
2756
+ '@smithy/hash-node': 4.2.8
2757
+ '@smithy/invalid-dependency': 4.2.8
2758
+ '@smithy/middleware-content-length': 4.2.8
2759
+ '@smithy/middleware-endpoint': 4.4.16
2760
+ '@smithy/middleware-retry': 4.4.33
2761
+ '@smithy/middleware-serde': 4.2.9
2762
+ '@smithy/middleware-stack': 4.2.8
2763
+ '@smithy/node-config-provider': 4.3.8
2764
+ '@smithy/node-http-handler': 4.4.10
2765
+ '@smithy/protocol-http': 5.3.8
2766
+ '@smithy/smithy-client': 4.11.5
2767
+ '@smithy/types': 4.12.0
2768
+ '@smithy/url-parser': 4.2.8
2769
+ '@smithy/util-base64': 4.3.0
2770
+ '@smithy/util-body-length-browser': 4.2.0
2771
+ '@smithy/util-body-length-node': 4.2.1
2772
+ '@smithy/util-defaults-mode-browser': 4.3.32
2773
+ '@smithy/util-defaults-mode-node': 4.2.35
2774
+ '@smithy/util-endpoints': 3.2.8
2775
+ '@smithy/util-middleware': 4.2.8
2776
+ '@smithy/util-retry': 4.2.8
2777
+ '@smithy/util-utf8': 4.2.0
2778
+ tslib: 2.8.1
2779
+ transitivePeerDependencies:
2780
+ - aws-crt
2781
+
2782
+ '@aws-sdk/core@3.973.11':
2783
+ dependencies:
2784
+ '@aws-sdk/types': 3.973.1
2785
+ '@aws-sdk/xml-builder': 3.972.5
2786
+ '@smithy/core': 3.23.2
2787
+ '@smithy/node-config-provider': 4.3.8
2788
+ '@smithy/property-provider': 4.2.8
2789
+ '@smithy/protocol-http': 5.3.8
2790
+ '@smithy/signature-v4': 5.3.8
2791
+ '@smithy/smithy-client': 4.11.5
2792
+ '@smithy/types': 4.12.0
2793
+ '@smithy/util-base64': 4.3.0
2794
+ '@smithy/util-middleware': 4.2.8
2795
+ '@smithy/util-utf8': 4.2.0
2796
+ tslib: 2.8.1
2797
+
2798
+ '@aws-sdk/crc64-nvme@3.972.0':
2799
+ dependencies:
2800
+ '@smithy/types': 4.12.0
2801
+ tslib: 2.8.1
2802
+
2803
+ '@aws-sdk/credential-provider-env@3.972.9':
2804
+ dependencies:
2805
+ '@aws-sdk/core': 3.973.11
2806
+ '@aws-sdk/types': 3.973.1
2807
+ '@smithy/property-provider': 4.2.8
2808
+ '@smithy/types': 4.12.0
2809
+ tslib: 2.8.1
2810
+
2811
+ '@aws-sdk/credential-provider-http@3.972.11':
2812
+ dependencies:
2813
+ '@aws-sdk/core': 3.973.11
2814
+ '@aws-sdk/types': 3.973.1
2815
+ '@smithy/fetch-http-handler': 5.3.9
2816
+ '@smithy/node-http-handler': 4.4.10
2817
+ '@smithy/property-provider': 4.2.8
2818
+ '@smithy/protocol-http': 5.3.8
2819
+ '@smithy/smithy-client': 4.11.5
2820
+ '@smithy/types': 4.12.0
2821
+ '@smithy/util-stream': 4.5.12
2822
+ tslib: 2.8.1
2823
+
2824
+ '@aws-sdk/credential-provider-ini@3.972.9':
2825
+ dependencies:
2826
+ '@aws-sdk/core': 3.973.11
2827
+ '@aws-sdk/credential-provider-env': 3.972.9
2828
+ '@aws-sdk/credential-provider-http': 3.972.11
2829
+ '@aws-sdk/credential-provider-login': 3.972.9
2830
+ '@aws-sdk/credential-provider-process': 3.972.9
2831
+ '@aws-sdk/credential-provider-sso': 3.972.9
2832
+ '@aws-sdk/credential-provider-web-identity': 3.972.9
2833
+ '@aws-sdk/nested-clients': 3.993.0
2834
+ '@aws-sdk/types': 3.973.1
2835
+ '@smithy/credential-provider-imds': 4.2.8
2836
+ '@smithy/property-provider': 4.2.8
2837
+ '@smithy/shared-ini-file-loader': 4.4.3
2838
+ '@smithy/types': 4.12.0
2839
+ tslib: 2.8.1
2840
+ transitivePeerDependencies:
2841
+ - aws-crt
2842
+
2843
+ '@aws-sdk/credential-provider-login@3.972.9':
2844
+ dependencies:
2845
+ '@aws-sdk/core': 3.973.11
2846
+ '@aws-sdk/nested-clients': 3.993.0
2847
+ '@aws-sdk/types': 3.973.1
2848
+ '@smithy/property-provider': 4.2.8
2849
+ '@smithy/protocol-http': 5.3.8
2850
+ '@smithy/shared-ini-file-loader': 4.4.3
2851
+ '@smithy/types': 4.12.0
2852
+ tslib: 2.8.1
2853
+ transitivePeerDependencies:
2854
+ - aws-crt
2855
+
2856
+ '@aws-sdk/credential-provider-node@3.972.10':
2857
+ dependencies:
2858
+ '@aws-sdk/credential-provider-env': 3.972.9
2859
+ '@aws-sdk/credential-provider-http': 3.972.11
2860
+ '@aws-sdk/credential-provider-ini': 3.972.9
2861
+ '@aws-sdk/credential-provider-process': 3.972.9
2862
+ '@aws-sdk/credential-provider-sso': 3.972.9
2863
+ '@aws-sdk/credential-provider-web-identity': 3.972.9
2864
+ '@aws-sdk/types': 3.973.1
2865
+ '@smithy/credential-provider-imds': 4.2.8
2866
+ '@smithy/property-provider': 4.2.8
2867
+ '@smithy/shared-ini-file-loader': 4.4.3
2868
+ '@smithy/types': 4.12.0
2869
+ tslib: 2.8.1
2870
+ transitivePeerDependencies:
2871
+ - aws-crt
2872
+
2873
+ '@aws-sdk/credential-provider-process@3.972.9':
2874
+ dependencies:
2875
+ '@aws-sdk/core': 3.973.11
2876
+ '@aws-sdk/types': 3.973.1
2877
+ '@smithy/property-provider': 4.2.8
2878
+ '@smithy/shared-ini-file-loader': 4.4.3
2879
+ '@smithy/types': 4.12.0
2880
+ tslib: 2.8.1
2881
+
2882
+ '@aws-sdk/credential-provider-sso@3.972.9':
2883
+ dependencies:
2884
+ '@aws-sdk/client-sso': 3.993.0
2885
+ '@aws-sdk/core': 3.973.11
2886
+ '@aws-sdk/token-providers': 3.993.0
2887
+ '@aws-sdk/types': 3.973.1
2888
+ '@smithy/property-provider': 4.2.8
2889
+ '@smithy/shared-ini-file-loader': 4.4.3
2890
+ '@smithy/types': 4.12.0
2891
+ tslib: 2.8.1
2892
+ transitivePeerDependencies:
2893
+ - aws-crt
2894
+
2895
+ '@aws-sdk/credential-provider-web-identity@3.972.9':
2896
+ dependencies:
2897
+ '@aws-sdk/core': 3.973.11
2898
+ '@aws-sdk/nested-clients': 3.993.0
2899
+ '@aws-sdk/types': 3.973.1
2900
+ '@smithy/property-provider': 4.2.8
2901
+ '@smithy/shared-ini-file-loader': 4.4.3
2902
+ '@smithy/types': 4.12.0
2903
+ tslib: 2.8.1
2904
+ transitivePeerDependencies:
2905
+ - aws-crt
2906
+
2907
+ '@aws-sdk/middleware-bucket-endpoint@3.972.3':
2908
+ dependencies:
2909
+ '@aws-sdk/types': 3.973.1
2910
+ '@aws-sdk/util-arn-parser': 3.972.2
2911
+ '@smithy/node-config-provider': 4.3.8
2912
+ '@smithy/protocol-http': 5.3.8
2913
+ '@smithy/types': 4.12.0
2914
+ '@smithy/util-config-provider': 4.2.0
2915
+ tslib: 2.8.1
2916
+
2917
+ '@aws-sdk/middleware-expect-continue@3.972.3':
2918
+ dependencies:
2919
+ '@aws-sdk/types': 3.973.1
2920
+ '@smithy/protocol-http': 5.3.8
2921
+ '@smithy/types': 4.12.0
2922
+ tslib: 2.8.1
2923
+
2924
+ '@aws-sdk/middleware-flexible-checksums@3.972.9':
2925
+ dependencies:
2926
+ '@aws-crypto/crc32': 5.2.0
2927
+ '@aws-crypto/crc32c': 5.2.0
2928
+ '@aws-crypto/util': 5.2.0
2929
+ '@aws-sdk/core': 3.973.11
2930
+ '@aws-sdk/crc64-nvme': 3.972.0
2931
+ '@aws-sdk/types': 3.973.1
2932
+ '@smithy/is-array-buffer': 4.2.0
2933
+ '@smithy/node-config-provider': 4.3.8
2934
+ '@smithy/protocol-http': 5.3.8
2935
+ '@smithy/types': 4.12.0
2936
+ '@smithy/util-middleware': 4.2.8
2937
+ '@smithy/util-stream': 4.5.12
2938
+ '@smithy/util-utf8': 4.2.0
2939
+ tslib: 2.8.1
2940
+
2941
+ '@aws-sdk/middleware-host-header@3.972.3':
2942
+ dependencies:
2943
+ '@aws-sdk/types': 3.973.1
2944
+ '@smithy/protocol-http': 5.3.8
2945
+ '@smithy/types': 4.12.0
2946
+ tslib: 2.8.1
2947
+
2948
+ '@aws-sdk/middleware-location-constraint@3.972.3':
2949
+ dependencies:
2950
+ '@aws-sdk/types': 3.973.1
2951
+ '@smithy/types': 4.12.0
2952
+ tslib: 2.8.1
2953
+
2954
+ '@aws-sdk/middleware-logger@3.972.3':
2955
+ dependencies:
2956
+ '@aws-sdk/types': 3.973.1
2957
+ '@smithy/types': 4.12.0
2958
+ tslib: 2.8.1
2959
+
2960
+ '@aws-sdk/middleware-recursion-detection@3.972.3':
2961
+ dependencies:
2962
+ '@aws-sdk/types': 3.973.1
2963
+ '@aws/lambda-invoke-store': 0.2.3
2964
+ '@smithy/protocol-http': 5.3.8
2965
+ '@smithy/types': 4.12.0
2966
+ tslib: 2.8.1
2967
+
2968
+ '@aws-sdk/middleware-sdk-s3@3.972.11':
2969
+ dependencies:
2970
+ '@aws-sdk/core': 3.973.11
2971
+ '@aws-sdk/types': 3.973.1
2972
+ '@aws-sdk/util-arn-parser': 3.972.2
2973
+ '@smithy/core': 3.23.2
2974
+ '@smithy/node-config-provider': 4.3.8
2975
+ '@smithy/protocol-http': 5.3.8
2976
+ '@smithy/signature-v4': 5.3.8
2977
+ '@smithy/smithy-client': 4.11.5
2978
+ '@smithy/types': 4.12.0
2979
+ '@smithy/util-config-provider': 4.2.0
2980
+ '@smithy/util-middleware': 4.2.8
2981
+ '@smithy/util-stream': 4.5.12
2982
+ '@smithy/util-utf8': 4.2.0
2983
+ tslib: 2.8.1
2984
+
2985
+ '@aws-sdk/middleware-ssec@3.972.3':
2986
+ dependencies:
2987
+ '@aws-sdk/types': 3.973.1
2988
+ '@smithy/types': 4.12.0
2989
+ tslib: 2.8.1
2990
+
2991
+ '@aws-sdk/middleware-user-agent@3.972.11':
2992
+ dependencies:
2993
+ '@aws-sdk/core': 3.973.11
2994
+ '@aws-sdk/types': 3.973.1
2995
+ '@aws-sdk/util-endpoints': 3.993.0
2996
+ '@smithy/core': 3.23.2
2997
+ '@smithy/protocol-http': 5.3.8
2998
+ '@smithy/types': 4.12.0
2999
+ tslib: 2.8.1
3000
+
3001
+ '@aws-sdk/nested-clients@3.993.0':
3002
+ dependencies:
3003
+ '@aws-crypto/sha256-browser': 5.2.0
3004
+ '@aws-crypto/sha256-js': 5.2.0
3005
+ '@aws-sdk/core': 3.973.11
3006
+ '@aws-sdk/middleware-host-header': 3.972.3
3007
+ '@aws-sdk/middleware-logger': 3.972.3
3008
+ '@aws-sdk/middleware-recursion-detection': 3.972.3
3009
+ '@aws-sdk/middleware-user-agent': 3.972.11
3010
+ '@aws-sdk/region-config-resolver': 3.972.3
3011
+ '@aws-sdk/types': 3.973.1
3012
+ '@aws-sdk/util-endpoints': 3.993.0
3013
+ '@aws-sdk/util-user-agent-browser': 3.972.3
3014
+ '@aws-sdk/util-user-agent-node': 3.972.10
3015
+ '@smithy/config-resolver': 4.4.6
3016
+ '@smithy/core': 3.23.2
3017
+ '@smithy/fetch-http-handler': 5.3.9
3018
+ '@smithy/hash-node': 4.2.8
3019
+ '@smithy/invalid-dependency': 4.2.8
3020
+ '@smithy/middleware-content-length': 4.2.8
3021
+ '@smithy/middleware-endpoint': 4.4.16
3022
+ '@smithy/middleware-retry': 4.4.33
3023
+ '@smithy/middleware-serde': 4.2.9
3024
+ '@smithy/middleware-stack': 4.2.8
3025
+ '@smithy/node-config-provider': 4.3.8
3026
+ '@smithy/node-http-handler': 4.4.10
3027
+ '@smithy/protocol-http': 5.3.8
3028
+ '@smithy/smithy-client': 4.11.5
3029
+ '@smithy/types': 4.12.0
3030
+ '@smithy/url-parser': 4.2.8
3031
+ '@smithy/util-base64': 4.3.0
3032
+ '@smithy/util-body-length-browser': 4.2.0
3033
+ '@smithy/util-body-length-node': 4.2.1
3034
+ '@smithy/util-defaults-mode-browser': 4.3.32
3035
+ '@smithy/util-defaults-mode-node': 4.2.35
3036
+ '@smithy/util-endpoints': 3.2.8
3037
+ '@smithy/util-middleware': 4.2.8
3038
+ '@smithy/util-retry': 4.2.8
3039
+ '@smithy/util-utf8': 4.2.0
3040
+ tslib: 2.8.1
3041
+ transitivePeerDependencies:
3042
+ - aws-crt
3043
+
3044
+ '@aws-sdk/region-config-resolver@3.972.3':
3045
+ dependencies:
3046
+ '@aws-sdk/types': 3.973.1
3047
+ '@smithy/config-resolver': 4.4.6
3048
+ '@smithy/node-config-provider': 4.3.8
3049
+ '@smithy/types': 4.12.0
3050
+ tslib: 2.8.1
3051
+
3052
+ '@aws-sdk/signature-v4-multi-region@3.995.0':
3053
+ dependencies:
3054
+ '@aws-sdk/middleware-sdk-s3': 3.972.11
3055
+ '@aws-sdk/types': 3.973.1
3056
+ '@smithy/protocol-http': 5.3.8
3057
+ '@smithy/signature-v4': 5.3.8
3058
+ '@smithy/types': 4.12.0
3059
+ tslib: 2.8.1
3060
+
3061
+ '@aws-sdk/token-providers@3.993.0':
3062
+ dependencies:
3063
+ '@aws-sdk/core': 3.973.11
3064
+ '@aws-sdk/nested-clients': 3.993.0
3065
+ '@aws-sdk/types': 3.973.1
3066
+ '@smithy/property-provider': 4.2.8
3067
+ '@smithy/shared-ini-file-loader': 4.4.3
3068
+ '@smithy/types': 4.12.0
3069
+ tslib: 2.8.1
3070
+ transitivePeerDependencies:
3071
+ - aws-crt
3072
+
3073
+ '@aws-sdk/types@3.973.1':
3074
+ dependencies:
3075
+ '@smithy/types': 4.12.0
3076
+ tslib: 2.8.1
3077
+
3078
+ '@aws-sdk/util-arn-parser@3.972.2':
3079
+ dependencies:
3080
+ tslib: 2.8.1
3081
+
3082
+ '@aws-sdk/util-endpoints@3.993.0':
3083
+ dependencies:
3084
+ '@aws-sdk/types': 3.973.1
3085
+ '@smithy/types': 4.12.0
3086
+ '@smithy/url-parser': 4.2.8
3087
+ '@smithy/util-endpoints': 3.2.8
3088
+ tslib: 2.8.1
3089
+
3090
+ '@aws-sdk/util-endpoints@3.995.0':
3091
+ dependencies:
3092
+ '@aws-sdk/types': 3.973.1
3093
+ '@smithy/types': 4.12.0
3094
+ '@smithy/url-parser': 4.2.8
3095
+ '@smithy/util-endpoints': 3.2.8
3096
+ tslib: 2.8.1
3097
+
3098
+ '@aws-sdk/util-locate-window@3.965.4':
3099
+ dependencies:
3100
+ tslib: 2.8.1
3101
+
3102
+ '@aws-sdk/util-user-agent-browser@3.972.3':
3103
+ dependencies:
3104
+ '@aws-sdk/types': 3.973.1
3105
+ '@smithy/types': 4.12.0
3106
+ bowser: 2.14.1
3107
+ tslib: 2.8.1
3108
+
3109
+ '@aws-sdk/util-user-agent-node@3.972.10':
3110
+ dependencies:
3111
+ '@aws-sdk/middleware-user-agent': 3.972.11
3112
+ '@aws-sdk/types': 3.973.1
3113
+ '@smithy/node-config-provider': 4.3.8
3114
+ '@smithy/types': 4.12.0
3115
+ tslib: 2.8.1
3116
+
3117
+ '@aws-sdk/xml-builder@3.972.5':
3118
+ dependencies:
3119
+ '@smithy/types': 4.12.0
3120
+ fast-xml-parser: 5.3.6
3121
+ tslib: 2.8.1
3122
+
3123
+ '@aws/lambda-invoke-store@0.2.3': {}
3124
+
3125
  '@babel/code-frame@7.29.0':
3126
  dependencies:
3127
  '@babel/helper-validator-identifier': 7.28.5
 
3571
  '@rollup/rollup-win32-x64-msvc@4.57.1':
3572
  optional: true
3573
 
3574
+ '@smithy/abort-controller@4.2.8':
3575
+ dependencies:
3576
+ '@smithy/types': 4.12.0
3577
+ tslib: 2.8.1
3578
+
3579
+ '@smithy/chunked-blob-reader-native@4.2.1':
3580
+ dependencies:
3581
+ '@smithy/util-base64': 4.3.0
3582
+ tslib: 2.8.1
3583
+
3584
+ '@smithy/chunked-blob-reader@5.2.0':
3585
+ dependencies:
3586
+ tslib: 2.8.1
3587
+
3588
+ '@smithy/config-resolver@4.4.6':
3589
+ dependencies:
3590
+ '@smithy/node-config-provider': 4.3.8
3591
+ '@smithy/types': 4.12.0
3592
+ '@smithy/util-config-provider': 4.2.0
3593
+ '@smithy/util-endpoints': 3.2.8
3594
+ '@smithy/util-middleware': 4.2.8
3595
+ tslib: 2.8.1
3596
+
3597
+ '@smithy/core@3.23.2':
3598
+ dependencies:
3599
+ '@smithy/middleware-serde': 4.2.9
3600
+ '@smithy/protocol-http': 5.3.8
3601
+ '@smithy/types': 4.12.0
3602
+ '@smithy/util-base64': 4.3.0
3603
+ '@smithy/util-body-length-browser': 4.2.0
3604
+ '@smithy/util-middleware': 4.2.8
3605
+ '@smithy/util-stream': 4.5.12
3606
+ '@smithy/util-utf8': 4.2.0
3607
+ '@smithy/uuid': 1.1.0
3608
+ tslib: 2.8.1
3609
+
3610
+ '@smithy/credential-provider-imds@4.2.8':
3611
+ dependencies:
3612
+ '@smithy/node-config-provider': 4.3.8
3613
+ '@smithy/property-provider': 4.2.8
3614
+ '@smithy/types': 4.12.0
3615
+ '@smithy/url-parser': 4.2.8
3616
+ tslib: 2.8.1
3617
+
3618
+ '@smithy/eventstream-codec@4.2.8':
3619
+ dependencies:
3620
+ '@aws-crypto/crc32': 5.2.0
3621
+ '@smithy/types': 4.12.0
3622
+ '@smithy/util-hex-encoding': 4.2.0
3623
+ tslib: 2.8.1
3624
+
3625
+ '@smithy/eventstream-serde-browser@4.2.8':
3626
+ dependencies:
3627
+ '@smithy/eventstream-serde-universal': 4.2.8
3628
+ '@smithy/types': 4.12.0
3629
+ tslib: 2.8.1
3630
+
3631
+ '@smithy/eventstream-serde-config-resolver@4.3.8':
3632
+ dependencies:
3633
+ '@smithy/types': 4.12.0
3634
+ tslib: 2.8.1
3635
+
3636
+ '@smithy/eventstream-serde-node@4.2.8':
3637
+ dependencies:
3638
+ '@smithy/eventstream-serde-universal': 4.2.8
3639
+ '@smithy/types': 4.12.0
3640
+ tslib: 2.8.1
3641
+
3642
+ '@smithy/eventstream-serde-universal@4.2.8':
3643
+ dependencies:
3644
+ '@smithy/eventstream-codec': 4.2.8
3645
+ '@smithy/types': 4.12.0
3646
+ tslib: 2.8.1
3647
+
3648
+ '@smithy/fetch-http-handler@5.3.9':
3649
+ dependencies:
3650
+ '@smithy/protocol-http': 5.3.8
3651
+ '@smithy/querystring-builder': 4.2.8
3652
+ '@smithy/types': 4.12.0
3653
+ '@smithy/util-base64': 4.3.0
3654
+ tslib: 2.8.1
3655
+
3656
+ '@smithy/hash-blob-browser@4.2.9':
3657
+ dependencies:
3658
+ '@smithy/chunked-blob-reader': 5.2.0
3659
+ '@smithy/chunked-blob-reader-native': 4.2.1
3660
+ '@smithy/types': 4.12.0
3661
+ tslib: 2.8.1
3662
+
3663
+ '@smithy/hash-node@4.2.8':
3664
+ dependencies:
3665
+ '@smithy/types': 4.12.0
3666
+ '@smithy/util-buffer-from': 4.2.0
3667
+ '@smithy/util-utf8': 4.2.0
3668
+ tslib: 2.8.1
3669
+
3670
+ '@smithy/hash-stream-node@4.2.8':
3671
+ dependencies:
3672
+ '@smithy/types': 4.12.0
3673
+ '@smithy/util-utf8': 4.2.0
3674
+ tslib: 2.8.1
3675
+
3676
+ '@smithy/invalid-dependency@4.2.8':
3677
+ dependencies:
3678
+ '@smithy/types': 4.12.0
3679
+ tslib: 2.8.1
3680
+
3681
+ '@smithy/is-array-buffer@2.2.0':
3682
+ dependencies:
3683
+ tslib: 2.8.1
3684
+
3685
+ '@smithy/is-array-buffer@4.2.0':
3686
+ dependencies:
3687
+ tslib: 2.8.1
3688
+
3689
+ '@smithy/md5-js@4.2.8':
3690
+ dependencies:
3691
+ '@smithy/types': 4.12.0
3692
+ '@smithy/util-utf8': 4.2.0
3693
+ tslib: 2.8.1
3694
+
3695
+ '@smithy/middleware-content-length@4.2.8':
3696
+ dependencies:
3697
+ '@smithy/protocol-http': 5.3.8
3698
+ '@smithy/types': 4.12.0
3699
+ tslib: 2.8.1
3700
+
3701
+ '@smithy/middleware-endpoint@4.4.16':
3702
+ dependencies:
3703
+ '@smithy/core': 3.23.2
3704
+ '@smithy/middleware-serde': 4.2.9
3705
+ '@smithy/node-config-provider': 4.3.8
3706
+ '@smithy/shared-ini-file-loader': 4.4.3
3707
+ '@smithy/types': 4.12.0
3708
+ '@smithy/url-parser': 4.2.8
3709
+ '@smithy/util-middleware': 4.2.8
3710
+ tslib: 2.8.1
3711
+
3712
+ '@smithy/middleware-retry@4.4.33':
3713
+ dependencies:
3714
+ '@smithy/node-config-provider': 4.3.8
3715
+ '@smithy/protocol-http': 5.3.8
3716
+ '@smithy/service-error-classification': 4.2.8
3717
+ '@smithy/smithy-client': 4.11.5
3718
+ '@smithy/types': 4.12.0
3719
+ '@smithy/util-middleware': 4.2.8
3720
+ '@smithy/util-retry': 4.2.8
3721
+ '@smithy/uuid': 1.1.0
3722
+ tslib: 2.8.1
3723
+
3724
+ '@smithy/middleware-serde@4.2.9':
3725
+ dependencies:
3726
+ '@smithy/protocol-http': 5.3.8
3727
+ '@smithy/types': 4.12.0
3728
+ tslib: 2.8.1
3729
+
3730
+ '@smithy/middleware-stack@4.2.8':
3731
+ dependencies:
3732
+ '@smithy/types': 4.12.0
3733
+ tslib: 2.8.1
3734
+
3735
+ '@smithy/node-config-provider@4.3.8':
3736
+ dependencies:
3737
+ '@smithy/property-provider': 4.2.8
3738
+ '@smithy/shared-ini-file-loader': 4.4.3
3739
+ '@smithy/types': 4.12.0
3740
+ tslib: 2.8.1
3741
+
3742
+ '@smithy/node-http-handler@4.4.10':
3743
+ dependencies:
3744
+ '@smithy/abort-controller': 4.2.8
3745
+ '@smithy/protocol-http': 5.3.8
3746
+ '@smithy/querystring-builder': 4.2.8
3747
+ '@smithy/types': 4.12.0
3748
+ tslib: 2.8.1
3749
+
3750
+ '@smithy/property-provider@4.2.8':
3751
+ dependencies:
3752
+ '@smithy/types': 4.12.0
3753
+ tslib: 2.8.1
3754
+
3755
+ '@smithy/protocol-http@5.3.8':
3756
+ dependencies:
3757
+ '@smithy/types': 4.12.0
3758
+ tslib: 2.8.1
3759
+
3760
+ '@smithy/querystring-builder@4.2.8':
3761
+ dependencies:
3762
+ '@smithy/types': 4.12.0
3763
+ '@smithy/util-uri-escape': 4.2.0
3764
+ tslib: 2.8.1
3765
+
3766
+ '@smithy/querystring-parser@4.2.8':
3767
+ dependencies:
3768
+ '@smithy/types': 4.12.0
3769
+ tslib: 2.8.1
3770
+
3771
+ '@smithy/service-error-classification@4.2.8':
3772
+ dependencies:
3773
+ '@smithy/types': 4.12.0
3774
+
3775
+ '@smithy/shared-ini-file-loader@4.4.3':
3776
+ dependencies:
3777
+ '@smithy/types': 4.12.0
3778
+ tslib: 2.8.1
3779
+
3780
+ '@smithy/signature-v4@5.3.8':
3781
+ dependencies:
3782
+ '@smithy/is-array-buffer': 4.2.0
3783
+ '@smithy/protocol-http': 5.3.8
3784
+ '@smithy/types': 4.12.0
3785
+ '@smithy/util-hex-encoding': 4.2.0
3786
+ '@smithy/util-middleware': 4.2.8
3787
+ '@smithy/util-uri-escape': 4.2.0
3788
+ '@smithy/util-utf8': 4.2.0
3789
+ tslib: 2.8.1
3790
+
3791
+ '@smithy/smithy-client@4.11.5':
3792
+ dependencies:
3793
+ '@smithy/core': 3.23.2
3794
+ '@smithy/middleware-endpoint': 4.4.16
3795
+ '@smithy/middleware-stack': 4.2.8
3796
+ '@smithy/protocol-http': 5.3.8
3797
+ '@smithy/types': 4.12.0
3798
+ '@smithy/util-stream': 4.5.12
3799
+ tslib: 2.8.1
3800
+
3801
+ '@smithy/types@4.12.0':
3802
+ dependencies:
3803
+ tslib: 2.8.1
3804
+
3805
+ '@smithy/url-parser@4.2.8':
3806
+ dependencies:
3807
+ '@smithy/querystring-parser': 4.2.8
3808
+ '@smithy/types': 4.12.0
3809
+ tslib: 2.8.1
3810
+
3811
+ '@smithy/util-base64@4.3.0':
3812
+ dependencies:
3813
+ '@smithy/util-buffer-from': 4.2.0
3814
+ '@smithy/util-utf8': 4.2.0
3815
+ tslib: 2.8.1
3816
+
3817
+ '@smithy/util-body-length-browser@4.2.0':
3818
+ dependencies:
3819
+ tslib: 2.8.1
3820
+
3821
+ '@smithy/util-body-length-node@4.2.1':
3822
+ dependencies:
3823
+ tslib: 2.8.1
3824
+
3825
+ '@smithy/util-buffer-from@2.2.0':
3826
+ dependencies:
3827
+ '@smithy/is-array-buffer': 2.2.0
3828
+ tslib: 2.8.1
3829
+
3830
+ '@smithy/util-buffer-from@4.2.0':
3831
+ dependencies:
3832
+ '@smithy/is-array-buffer': 4.2.0
3833
+ tslib: 2.8.1
3834
+
3835
+ '@smithy/util-config-provider@4.2.0':
3836
+ dependencies:
3837
+ tslib: 2.8.1
3838
+
3839
+ '@smithy/util-defaults-mode-browser@4.3.32':
3840
+ dependencies:
3841
+ '@smithy/property-provider': 4.2.8
3842
+ '@smithy/smithy-client': 4.11.5
3843
+ '@smithy/types': 4.12.0
3844
+ tslib: 2.8.1
3845
+
3846
+ '@smithy/util-defaults-mode-node@4.2.35':
3847
+ dependencies:
3848
+ '@smithy/config-resolver': 4.4.6
3849
+ '@smithy/credential-provider-imds': 4.2.8
3850
+ '@smithy/node-config-provider': 4.3.8
3851
+ '@smithy/property-provider': 4.2.8
3852
+ '@smithy/smithy-client': 4.11.5
3853
+ '@smithy/types': 4.12.0
3854
+ tslib: 2.8.1
3855
+
3856
+ '@smithy/util-endpoints@3.2.8':
3857
+ dependencies:
3858
+ '@smithy/node-config-provider': 4.3.8
3859
+ '@smithy/types': 4.12.0
3860
+ tslib: 2.8.1
3861
+
3862
+ '@smithy/util-hex-encoding@4.2.0':
3863
+ dependencies:
3864
+ tslib: 2.8.1
3865
+
3866
+ '@smithy/util-middleware@4.2.8':
3867
+ dependencies:
3868
+ '@smithy/types': 4.12.0
3869
+ tslib: 2.8.1
3870
+
3871
+ '@smithy/util-retry@4.2.8':
3872
+ dependencies:
3873
+ '@smithy/service-error-classification': 4.2.8
3874
+ '@smithy/types': 4.12.0
3875
+ tslib: 2.8.1
3876
+
3877
+ '@smithy/util-stream@4.5.12':
3878
+ dependencies:
3879
+ '@smithy/fetch-http-handler': 5.3.9
3880
+ '@smithy/node-http-handler': 4.4.10
3881
+ '@smithy/types': 4.12.0
3882
+ '@smithy/util-base64': 4.3.0
3883
+ '@smithy/util-buffer-from': 4.2.0
3884
+ '@smithy/util-hex-encoding': 4.2.0
3885
+ '@smithy/util-utf8': 4.2.0
3886
+ tslib: 2.8.1
3887
+
3888
+ '@smithy/util-uri-escape@4.2.0':
3889
+ dependencies:
3890
+ tslib: 2.8.1
3891
+
3892
+ '@smithy/util-utf8@2.3.0':
3893
+ dependencies:
3894
+ '@smithy/util-buffer-from': 2.2.0
3895
+ tslib: 2.8.1
3896
+
3897
+ '@smithy/util-utf8@4.2.0':
3898
+ dependencies:
3899
+ '@smithy/util-buffer-from': 4.2.0
3900
+ tslib: 2.8.1
3901
+
3902
+ '@smithy/util-waiter@4.2.8':
3903
+ dependencies:
3904
+ '@smithy/abort-controller': 4.2.8
3905
+ '@smithy/types': 4.12.0
3906
+ tslib: 2.8.1
3907
+
3908
+ '@smithy/uuid@1.1.0':
3909
+ dependencies:
3910
+ tslib: 2.8.1
3911
+
3912
  '@tootallnate/quickjs-emscripten@0.23.0': {}
3913
 
3914
  '@types/babel__core@7.20.5':
 
4098
 
4099
  binary-extensions@2.3.0: {}
4100
 
4101
+ bowser@2.14.1: {}
4102
+
4103
  brace-expansion@2.0.2:
4104
  dependencies:
4105
  balanced-match: 1.0.2
 
4405
 
4406
  fast-uri@3.1.0: {}
4407
 
4408
+ fast-xml-parser@5.3.6:
4409
+ dependencies:
4410
+ strnum: 2.1.2
4411
+
4412
  fastify-plugin@4.5.1: {}
4413
 
4414
  fastify@4.29.1:
 
5178
  optionalDependencies:
5179
  '@types/node': 20.19.33
5180
 
5181
+ strnum@2.1.2: {}
5182
+
5183
  sucrase@3.35.1:
5184
  dependencies:
5185
  '@jridgewell/gen-mapping': 0.3.13