From f1e93ef9d8ddc5cc6e30d99987d618bd22e93355 Mon Sep 17 00:00:00 2001 From: MisterPapaye Date: Thu, 29 Jan 2026 21:58:18 +0100 Subject: [PATCH 01/46] Create db.silvernote.ts --- src/assets/ts/db/db.silvernote.ts | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/assets/ts/db/db.silvernote.ts diff --git a/src/assets/ts/db/db.silvernote.ts b/src/assets/ts/db/db.silvernote.ts new file mode 100644 index 0000000..ce456e0 --- /dev/null +++ b/src/assets/ts/db/db.silvernote.ts @@ -0,0 +1,43 @@ +import nodeFetch from 'node-fetch'; + + + +async function fetch( + path: string, + opt: { + method?: 'POST' | 'GET' | 'DELETE', + body?: string + } = { method: 'GET' } +): Promise { + + try { + + const res = await nodeFetch('https://db.silvernote.fr' + path, { + method: opt.method || 'GET', + body: opt.body, + headers: { + "Authorization": process.env.DB_API_SK_1 || "", + "X-API-Key": process.env.DB_API_SK_2 || "", + "Content-Type": "application/json" + }, + }); + + if (!res.ok) { + const errorText = await res.text(); + console.error(`Erreur API ${res.status} : `, errorText); + return null; + } + + return await res.json(); + + } catch (error) { + console.error("Erreur réseau/fetch:", error); + return null; + } + +} + + +export { + fetch +} \ No newline at end of file From 1c2423610a4c43766eebb92721a95b92f29729bb Mon Sep 17 00:00:00 2001 From: MisterPapaye Date: Thu, 29 Jan 2026 21:58:24 +0100 Subject: [PATCH 02/46] Update api.share.ts --- src/routes/api.share.ts | 83 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 76 insertions(+), 7 deletions(-) diff --git a/src/routes/api.share.ts b/src/routes/api.share.ts index 5327900..020ce9c 100644 --- a/src/routes/api.share.ts +++ b/src/routes/api.share.ts @@ -36,7 +36,7 @@ router.get('/:uuid', async (req, res) => { const now = Date.now(); const isExpired: boolean = now - createdTime > TheShare.params.age; - if (TheShare.params.age !== -1 &&isExpired) { + if (TheShare.params.age !== -1 && isExpired) { Share.delete(uuid); res.json({ expired: isExpired }); return; @@ -67,10 +67,19 @@ router.get('/:uuid/info', async (req, res) => { const _share = await Share.get(uuid); - res.json({ + if (!_share) { + res.json({ success: false, error: true, message: 'Partage non trouvée.' }); + return; + } + + res.json({ + success: true, share: { ..._share, - params: {} + params: { + ..._share.params, + passwd: _share.params.passwd ? true : false + } } }); return; @@ -84,6 +93,12 @@ router.post('/create', async (req, res) => { try { + if (!user_id || !note_uuid || !params) + { + res.json({ error: true, message: 'Missing parameters.' }); + return; + } + if (await Share.get(note_uuid)) { await Share.delete(note_uuid); } @@ -93,7 +108,7 @@ router.post('/create', async (req, res) => { owner_id: user_id, } - const TheShare = await Share.add({ + await Share.add({ uuid: note_uuid, owner_id: user_id, @@ -101,7 +116,7 @@ router.post('/create', async (req, res) => { params, - created_at: new Date().toString(), + created_at: new Date().toISOString(), expires_at: "", visitor: [], @@ -121,9 +136,10 @@ router.post('/create', async (req, res) => { }) -router.post('/ban', async (req, res) => { +router.post('/:uuid/ban', async (req, res) => { - const { uuid, banned_id } = req.body; + const { banned_id } = req.body; + const uuid = req.params.uuid; try { @@ -153,6 +169,58 @@ router.post('/ban', async (req, res) => { }) +router.post('/:uuid/update', async (req, res) => { + + const { share } = req.body; + const uuid = req.params.uuid; + + + try { + + const TheShare = await Share.get(uuid); + + if (TheShare) { + + const updatedShare = { ...TheShare, ...share, params: { passwd: TheShare.params.passwd, ...share.params } }; + + await Share.update(updatedShare!); + + res.json({ success: true, share: updatedShare }); + return; + + } + + res.json({ success: false }); + return; + + } + + catch (err) { + res.status(500).json({ error: true, message: err }); + return; + } + +}) + +router.post('/:uuid/delete', async (req, res) => { + + const uuid = req.params.uuid; + + try { + + await Share.delete(uuid); + + res.json({ success: true }); + + } + catch (err) { + res.status(500).json({ error: true, message: err }); + return; + } + +}) + + router.get('/for/me', async (req, res) => { const { user_id } = req.cookies; @@ -219,6 +287,7 @@ router.get('/by/me', async (req, res) => { for (const share of my_share) { const __note = await notes.getNoteByUUID(share.note_uuid); + console.log(share) if (!__note.note) continue; _notes.push(__note.note); } From b6d69e402dfb6ab258ef66dd7aded1847c75350d Mon Sep 17 00:00:00 2001 From: MisterPapaye Date: Thu, 29 Jan 2026 21:58:26 +0100 Subject: [PATCH 03/46] Create resources.ts --- src/routes/resources.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/routes/resources.ts diff --git a/src/routes/resources.ts b/src/routes/resources.ts new file mode 100644 index 0000000..09d5ac5 --- /dev/null +++ b/src/routes/resources.ts @@ -0,0 +1,27 @@ +import { Router, Request, Response } from 'express'; +import { fetch } from '../assets/ts/db/db.silvernote.js'; + + +const router = Router(); + + +router.get('/test', async (req: Request, res: Response) => { + res.json({ test: true }); +}) + + +router.get('/db/length', async (req: Request, res: Response) => { + + const notesLength = await fetch('/notes/length'); + const tagsLength = await fetch('/tags/length'); + + res.json({ + notes: notesLength, + tags: tagsLength + }); + +}) + + + +export default router; From f25b136792a4450ae042ff27f0be5ecfafacd9c8 Mon Sep 17 00:00:00 2001 From: MisterPapaye Date: Thu, 29 Jan 2026 22:26:28 +0100 Subject: [PATCH 04/46] add users length on resources --- src/express.ts | 2 ++ src/routes/resources.ts | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/express.ts b/src/express.ts index f2a7ec5..fa1cfff 100644 --- a/src/express.ts +++ b/src/express.ts @@ -26,6 +26,7 @@ import api_share from './routes/api.share.js'; import user from './routes/user.js'; import money from './routes/money.js'; import admin from './routes/admin.js'; +import resources from './routes/resources.js'; const app = express(); const httpServer = createServer(app); @@ -85,6 +86,7 @@ app.use('/api/ai', api_ai); app.use('/user', user); app.use('/admin', admin); app.use('/money', money); +app.use('/resources', resources); app.use('/api/db', requireAuth(), api_db); diff --git a/src/routes/resources.ts b/src/routes/resources.ts index 09d5ac5..90d9952 100644 --- a/src/routes/resources.ts +++ b/src/routes/resources.ts @@ -1,5 +1,6 @@ import { Router, Request, Response } from 'express'; import { fetch } from '../assets/ts/db/db.silvernote.js'; +import { clerkClient } from '@clerk/clerk-sdk-node'; const router = Router(); @@ -23,5 +24,17 @@ router.get('/db/length', async (req: Request, res: Response) => { }) +router.get('/clerk/users/length', async (req: Request, res: Response) => { + + const data = await clerkClient.users.getCount() + + res.json({ + users: data || null + }); + +}); + + + export default router; From f302cd9fe693bbe6cab27a0451d032150d900e76 Mon Sep 17 00:00:00 2001 From: MisterPapaye Date: Fri, 30 Jan 2026 20:57:47 +0100 Subject: [PATCH 05/46] add LICENSE + update resources routes --- LICENSE | 13 +++++++ src/routes/resources.ts | 77 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..43a74aa --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ +Copyright © 2026 Silvercore + +Tous droits réservés / All Rights Reserved + +Le code source de ce projet est rendu public uniquement à des fins +de transparence. Aucune licence d'utilisation, de modification, de +distribution ou de reproduction n'est accordée. + +This source code is made publicly available for transparency purposes +only. No license to use, modify, distribute, or reproduce is granted. + +Toute utilisation non autorisée de ce code est strictement interdite. +Unauthorized use of this code is strictly prohibited. diff --git a/src/routes/resources.ts b/src/routes/resources.ts index 90d9952..f57596c 100644 --- a/src/routes/resources.ts +++ b/src/routes/resources.ts @@ -1,6 +1,7 @@ import { Router, Request, Response } from 'express'; import { fetch } from '../assets/ts/db/db.silvernote.js'; import { clerkClient } from '@clerk/clerk-sdk-node'; +import nodeFetch from 'node-fetch'; const router = Router(); @@ -36,5 +37,81 @@ router.get('/clerk/users/length', async (req: Request, res: Response) => { +router.get('/status/sites', async (req: Request, res: Response) => { + + try { + + const apiKey = process.env.CRONITOR_API_KEY; + + if (!apiKey) { + throw new Error('Missing CRONITOR_API_KEY in environment'); + } + + const auth = Buffer.from(`${apiKey}:`).toString('base64'); + + const response = await nodeFetch('https://cronitor.io/api/monitors', { + method: 'GET', + headers: { + 'Authorization': `Basic ${auth}`, + 'Content-Type': 'application/json' + } + }); + + if (!response.ok) { + throw new Error(`Cronitor API responded with ${response.status}`); + } + + const data = await response.json(); + + const sites = data.monitors.map((m: any) => { + + const latest = m.latest_event || {}; + const ssl = m.attributes?.site?.ssl || {}; + + return { + + key: m.key, + name: m.name.replace(/\(.*\)/, '').trim(), + url: m.request?.url, + is_online: m.passing && !m.paused, + status: m.paused ? 'paused' : (m.passing ? 'operational' : 'degraded'), + + // Métriques de performance + metrics: { + latency: latest.metrics?.duration ? Math.round(latest.metrics.duration * 1000) : null, // ms + last_check_region: latest.host || 'N/A', + last_check_at: m.latest_event?.stamp ? new Date(m.latest_event.stamp * 1000).toISOString() : null + }, + + // Sécurité (Très utile pour prévenir plutôt que guérir) + ssl: { + expires_at: ssl.expires_at || null, + is_valid: ssl.expires_at ? new Date(ssl.expires_at) > new Date() : false, + provider: ssl.issued_by || 'Unknown' + }, + + // Configuration + schedule: m.schedule, + badge: m.public_badge_url + + }; + + }); + + res.json({ + success: true, + data: sites + }); + + } catch (error: any) { + console.error('Error fetching Cronitor status:', error.message); + res.status(500).json({ + success: false, + error: error.message + }); + } + +}); + export default router; From b9f6c79926dd590edea31fc789f3ed0bf7418323 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Wed, 4 Feb 2026 10:10:56 +0100 Subject: [PATCH 06/46] Create .env.example --- .env.example | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..c3ce6a4 --- /dev/null +++ b/.env.example @@ -0,0 +1,24 @@ +COOKIE_SIGN_KEY=key +JWT_SIGN_KEY=key +secret_token_key=key +DB_ENCRYPTION_KEY=key + +DB_API_SK_1=key +DB_API_SK_2=key + +secret_admin_api_key=key +SECRET_AI_API_KEY=key +MOBILE_SECRET_KEY=key + +STRIPE_SECRET_KEY=key +STRIPE_WEBHOOK_SECRET=key + +OPENAI_SECRET_KEY=sk-proj-key +GOOGLE_API_KEY=key + +CLERK_PUBLISHABLE_KEY=key +CLERK_SECRET_KEY=key + +MCP_SERVER_PATH=./src/mcp-server/index.js + +CRONITOR_API_KEY=key \ No newline at end of file From a5831ec1cd603fb58a1cea1d10ea9c3e6f4aaac4 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Wed, 4 Feb 2026 10:10:59 +0100 Subject: [PATCH 07/46] Create scrypto.ts --- src/assets/ts/utils/scrypto/scrypto.ts | 53 ++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/assets/ts/utils/scrypto/scrypto.ts diff --git a/src/assets/ts/utils/scrypto/scrypto.ts b/src/assets/ts/utils/scrypto/scrypto.ts new file mode 100644 index 0000000..6b92ec3 --- /dev/null +++ b/src/assets/ts/utils/scrypto/scrypto.ts @@ -0,0 +1,53 @@ +import crypto from 'crypto'; + + +const rawKey = process.env.DB_ENCRYPTION_KEY; + +if (!rawKey || rawKey.length !== 64) { + throw new Error("La clé DB_ENCRYPTION_KEY doit faire 64 caractères hexadécimaux (32 octets)."); +} + +const ENCRYPTION_KEY = Buffer.from(rawKey, 'hex'); +const ALGORITHM = 'aes-256-gcm'; + + +function encrypt(text: string) +{ + + // generate random iv and cipher + const iv = crypto.randomBytes(12); + const cipher = crypto.createCipheriv(ALGORITHM, Buffer.from(ENCRYPTION_KEY), iv); + + // encrypt the text + let encrypted = cipher.update(text, 'utf8', 'hex'); + encrypted += cipher.final('hex'); + const authTag = cipher.getAuthTag().toString('hex'); + + // return iv, authTag and encrypted text concatenated + return `${iv.toString('hex')}:${authTag}:${encrypted}`; + +} + +function decrypt(data: string) +{ + + // split the data into its components + const [ivHex, authTagHex, encryptedText] = data.split(':'); + const decipher = crypto.createDecipheriv( + ALGORITHM, + Buffer.from(ENCRYPTION_KEY), + Buffer.from(ivHex, 'hex') + ); + decipher.setAuthTag(Buffer.from(authTagHex, 'hex')); + + // decrypt the text + let decrypted = decipher.update(encryptedText, 'hex', 'utf8'); + decrypted += decipher.final('utf8'); + + return decrypted; + +} + +export { + encrypt, + decrypt }; \ No newline at end of file From 248752c92fdd4f49ed13ad505a3901058beb5aeb Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Wed, 4 Feb 2026 10:11:23 +0100 Subject: [PATCH 08/46] =?UTF-8?q?impl=C3=A9ment=20scrypto=20to=20note=20cl?= =?UTF-8?q?ass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/ts/notes.ts | 79 ++++++++++++++++++++++++++++++++++++++---- src/assets/ts/types.ts | 1 + 2 files changed, 73 insertions(+), 7 deletions(-) diff --git a/src/assets/ts/notes.ts b/src/assets/ts/notes.ts index ec3c28d..dc6fb34 100644 --- a/src/assets/ts/notes.ts +++ b/src/assets/ts/notes.ts @@ -2,6 +2,7 @@ import nodeFetch from 'node-fetch'; import type { Note } from "./types.js"; import { randomUUID } from "crypto"; import 'dotenv/config'; +import { decrypt, encrypt } from './utils/scrypto/scrypto.js'; class Notes { @@ -60,11 +61,18 @@ import 'dotenv/config'; if (!note.user_id) return { error: true, message: "user_id requis" }; note.uuid = note.uuid || randomUUID(); - note.created_at = note.created_at || Date.now(); + note.created_at = Date.now(); + + const noteToStore = { ...note }; + if (noteToStore.content) + { + noteToStore.content = encrypt(noteToStore.content); + noteToStore.content_type = "text/html/crypted"; + } const res = await this.fetch('/push', { method: 'POST', - body: JSON.stringify({ note }) + body: JSON.stringify({ note: noteToStore }) }) return { success: res?._id ? true : false, note }; @@ -80,17 +88,67 @@ import 'dotenv/config'; if (note && note.uuid) { - return { success: true, note }; + + if (note.content_type === "text/html/crypted" && note.content) + { + + if (note.content && note.content.includes(':')) + { + + try { + note.content = decrypt(note.content); + return { success: true, note }; + } + catch (e) { + console.error("Error on decrypting note : ", note.uuid); + return { success: false, error: true, message: "Error on decrypting note" }; + } + + } + + } + else + { + return { success: true, note }; + } + + } + else + { + return { error: true, message: "Note introuvable" }; } - else return { error: true, message: "Note introuvable" }; + + return { error: true, message: "Note introuvable" }; } public async getNoteByUserId(user_id: string) { const notes: Note[] = await this.fetch(`/get/byuserid/${user_id}`); + const decryptedNotes: Note[] = []; + + for (const note of notes) + { + + if (note.content_type === "text/html/crypted" && note.content) + { - return { success: true, notes }; + try { + note.content = decrypt(note.content); + decryptedNotes.push(note); + } catch (e) { + console.error("Error on decrypting note : ", note.uuid); + } + + } + else + { + decryptedNotes.push(note); + } + + } + + return { success: true, notes: decryptedNotes }; } @@ -99,10 +157,17 @@ import 'dotenv/config'; if (!note.uuid || !note.user_id) { return { error: true, message: "uuid et user_id requis" }; } + + const noteToStore = { ...note }; + if (noteToStore.content) + { + noteToStore.content = encrypt(noteToStore.content); + noteToStore.content_type = "text/html/crypted"; + } const res = await this.fetch('/update', { method: "POST", - body: JSON.stringify({ note }) + body: JSON.stringify({ note: noteToStore }) }); if (res.error) { @@ -110,7 +175,7 @@ import 'dotenv/config'; } if (res.uuid) { - return { success: true, note }; + return { success: true, note: note }; } return { error: true, message: "réponse inattendue", res }; diff --git a/src/assets/ts/types.ts b/src/assets/ts/types.ts index efc51a3..33f1a9c 100644 --- a/src/assets/ts/types.ts +++ b/src/assets/ts/types.ts @@ -31,6 +31,7 @@ export interface Note { icon?: string; title: string; content: string; + content_type?: "text/plain" | "text/markdown" | "text/html" | "text/html/crypted"; tags?: string[]; pinned?: boolean; created_at?: number; From 88e9b997a520cd633324c914fe563af91139cf59 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Wed, 4 Feb 2026 10:47:13 +0100 Subject: [PATCH 09/46] add fingerprint and update scrypto --- src/assets/ts/notes.ts | 8 ++--- src/assets/ts/utils/scrypto/scrypto.ts | 42 ++++++++++++++++++++++---- src/routes/api.db.ts | 16 ++++++++++ 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/assets/ts/notes.ts b/src/assets/ts/notes.ts index dc6fb34..7649d5a 100644 --- a/src/assets/ts/notes.ts +++ b/src/assets/ts/notes.ts @@ -66,7 +66,7 @@ import { decrypt, encrypt } from './utils/scrypto/scrypto.js'; const noteToStore = { ...note }; if (noteToStore.content) { - noteToStore.content = encrypt(noteToStore.content); + noteToStore.content = encrypt(noteToStore.content, note.user_id); noteToStore.content_type = "text/html/crypted"; } @@ -96,7 +96,7 @@ import { decrypt, encrypt } from './utils/scrypto/scrypto.js'; { try { - note.content = decrypt(note.content); + note.content = decrypt(note.content, note.user_id); return { success: true, note }; } catch (e) { @@ -134,7 +134,7 @@ import { decrypt, encrypt } from './utils/scrypto/scrypto.js'; { try { - note.content = decrypt(note.content); + note.content = decrypt(note.content, note.user_id); decryptedNotes.push(note); } catch (e) { console.error("Error on decrypting note : ", note.uuid); @@ -161,7 +161,7 @@ import { decrypt, encrypt } from './utils/scrypto/scrypto.js'; const noteToStore = { ...note }; if (noteToStore.content) { - noteToStore.content = encrypt(noteToStore.content); + noteToStore.content = encrypt(noteToStore.content, note.user_id); noteToStore.content_type = "text/html/crypted"; } diff --git a/src/assets/ts/utils/scrypto/scrypto.ts b/src/assets/ts/utils/scrypto/scrypto.ts index 6b92ec3..d215a8b 100644 --- a/src/assets/ts/utils/scrypto/scrypto.ts +++ b/src/assets/ts/utils/scrypto/scrypto.ts @@ -7,16 +7,42 @@ if (!rawKey || rawKey.length !== 64) { throw new Error("La clé DB_ENCRYPTION_KEY doit faire 64 caractères hexadécimaux (32 octets)."); } -const ENCRYPTION_KEY = Buffer.from(rawKey, 'hex'); +const MASTER_KEY = Buffer.from(rawKey, 'hex'); const ALGORITHM = 'aes-256-gcm'; -function encrypt(text: string) +function getUserKey(userId: string): Buffer { + + return crypto.hkdfSync( + 'sha256', + MASTER_KEY, + Buffer.alloc(0), // Salt (optionnel, vide ici) + `user-key-${userId}`, // Info : contexte unique + 32 // Longueur de clé désirée + ) as Buffer; + +} + +function getUserFingerprint(userId: string): string { + const userKey = getUserKey(userId); + return crypto.createHash('sha256') + .update(Buffer.from(userKey)) + .digest('hex') + .toUpperCase() + .match(/.{1,4}/g)! + .slice(0, 8) + .join('-'); +} + + +function encrypt(text: string, userId: string) { + const userKey = getUserKey(userId); + // generate random iv and cipher const iv = crypto.randomBytes(12); - const cipher = crypto.createCipheriv(ALGORITHM, Buffer.from(ENCRYPTION_KEY), iv); + const cipher = crypto.createCipheriv(ALGORITHM, userKey, iv); // encrypt the text let encrypted = cipher.update(text, 'utf8', 'hex'); @@ -28,14 +54,16 @@ function encrypt(text: string) } -function decrypt(data: string) +function decrypt(data: string, userId: string) { + const userKey = getUserKey(userId); + // split the data into its components const [ivHex, authTagHex, encryptedText] = data.split(':'); const decipher = crypto.createDecipheriv( ALGORITHM, - Buffer.from(ENCRYPTION_KEY), + userKey, Buffer.from(ivHex, 'hex') ); decipher.setAuthTag(Buffer.from(authTagHex, 'hex')); @@ -50,4 +78,6 @@ function decrypt(data: string) export { encrypt, - decrypt }; \ No newline at end of file + decrypt, + getUserFingerprint +}; \ No newline at end of file diff --git a/src/routes/api.db.ts b/src/routes/api.db.ts index 5146463..85df0ca 100644 --- a/src/routes/api.db.ts +++ b/src/routes/api.db.ts @@ -11,6 +11,7 @@ import axios from 'axios'; import FormData from "form-data"; import downloadFile from "../assets/ts/downloadFile.js"; import { fileURLToPath } from "url"; +import { getUserFingerprint } from "../assets/ts/utils/scrypto/scrypto.js"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -56,6 +57,21 @@ router.post('/verify/data', async (req: Request, res: Response) => { }); +router.get('/get/scrypto/fingerprint', async (req: Request, res: Response) => { + + const userId = req.cookies.user_id; + if (!userId) { + res.status(400).json({ error: true, message: 'user_id cookie is required.' }); + return; + } + + const fingerprint = getUserFingerprint(userId); + + res.json({ fingerprint }); + +}); + + // for notes router.post('/new/note', async (req: Request, res: Response) => { From 9bee342a0149d2d44d63333222d40d0f3a075a31 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Wed, 4 Feb 2026 15:18:31 +0100 Subject: [PATCH 10/46] create /news route --- src/routes/api.ts | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/routes/api.ts b/src/routes/api.ts index 4b0efaf..5f59729 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -1,19 +1,17 @@ import { Router, Request, Response } from 'express'; -import fs from 'fs'; -import type { News } from '../assets/ts/types.js'; import { clerkClient } from "@clerk/express"; import { randomUUID } from 'crypto'; +import News from '../assets/ts/news.js'; const router = Router(); -router.get('/get_news', async (req: Request, res: Response) => { +router.get('/news', (req: Request, res: Response) => { - const data = await fs.promises.readFile(process.env.CONFIG_PATH || './dist/config.json', 'utf-8'); // remettre ./config pour prod - const news: Promise = JSON.parse(data).news; + const news = News.getAllNews(); - res.json( (await news).active ? news : false ); + res.json(news); }) @@ -38,4 +36,19 @@ router.get('/user/by/id/:userid', async (req, res) => { }) +router.get('/notifications', async (req, res) => { + + const client_userId = req.cookies.user_id; + + if (!client_userId) { + return res.status(401).json({ error: 'Unauthorized' }); + } + + const notifications = await clerkClient.users.getUserNotifications(client_userId); + + res.json({ notifications }); + +}); + + export default router; From 4d6d93ef7ba4c44e4791b31051919520500ee5d6 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Wed, 4 Feb 2026 15:18:37 +0100 Subject: [PATCH 11/46] Create news.ts --- src/assets/ts/news.ts | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/assets/ts/news.ts diff --git a/src/assets/ts/news.ts b/src/assets/ts/news.ts new file mode 100644 index 0000000..b859192 --- /dev/null +++ b/src/assets/ts/news.ts @@ -0,0 +1,37 @@ +import fs from 'fs'; +import path from 'path'; +import __dirname from './_dirname.js'; + +interface NewsItem { + id: number; + title: string; + content: string; // md format + date: Date; +} + +class News +{ + + private getNewsFile (): NewsItem[] + { + return JSON.parse(fs.readFileSync(path.join(__dirname, '../config/news.json'), 'utf-8')); + } + + public getAllNews (): NewsItem[] + { + return this.getNewsFile(); + } + + public getLastNews (count: number): NewsItem[] + { + const news = this.getNewsFile(); + return news.slice(0, count); + } + +} + +export default new News(); + +export { + type NewsItem +} \ No newline at end of file From 413df232977bd8f7484413234796e10d1a7f9642 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Wed, 4 Feb 2026 15:18:45 +0100 Subject: [PATCH 12/46] Create news.json --- src/assets/config/news.json | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/assets/config/news.json diff --git a/src/assets/config/news.json b/src/assets/config/news.json new file mode 100644 index 0000000..1935949 --- /dev/null +++ b/src/assets/config/news.json @@ -0,0 +1,32 @@ +[ + { + "id": 1, + "title": "Nouvelle mise à jour disponible !", + "content": "## Version 1.5 est là !\n\nNous avons ajouté plusieurs améliorations :\n- Mode sombre pour vos notes 🌙\n- Recherche plus rapide 🔍\n- Correction de bugs mineurs 🐞\n\nMettez à jour pour profiter de ces nouveautés !", + "date": "2026-02-04T09:00:00Z" + }, + { + "id": 2, + "title": "Astuce du jour : organiser vos notes", + "content": "### Classez vos notes par tags\n\nUtilisez des **tags** pour mieux organiser vos notes et retrouver vos idées en un clin d'œil.\n\nExemple :\n- `#travail`\n- `#personnel`\n- `#projets`", + "date": "2026-02-03T14:30:00Z" + }, + { + "id": 3, + "title": "Mini-jeux intégrés à Silvernote !", + "content": "Pour rendre vos pauses plus fun, nous avons ajouté **des mini-jeux** :\n- 🐍 Snake\n- 🔢 2048\n- 🧩 Puzzle rapide\n\nAccédez à eux depuis le menu **Divertissement** !", + "date": "2026-02-02T10:15:00Z" + }, + { + "id": 4, + "title": "Synchronisation cloud améliorée", + "content": "La synchronisation de vos notes avec le cloud est **plus rapide et fiable**.\n\n- Synchronisation automatique en arrière-plan ☁️\n- Moins de conflits entre appareils\n- Historique de versions amélioré 📜", + "date": "2026-02-01T08:45:00Z" + }, + { + "id": 5, + "title": "Partage de notes simplifié", + "content": "Vous pouvez maintenant **partager vos notes** avec vos amis ou collègues en un clic :\n\n- Générez un lien public 🌐\n- Définissez les permissions (lecture seule ou modification)\n- Partage rapide via email ou messagerie 📧", + "date": "2026-01-31T16:00:00Z" + } +] From 6b745ea3272a6b769b5318a0a93d61c9973fb2e5 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Wed, 4 Feb 2026 15:18:48 +0100 Subject: [PATCH 13/46] Create notifications.ts --- src/assets/ts/db/notifications.ts | 119 ++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/assets/ts/db/notifications.ts diff --git a/src/assets/ts/db/notifications.ts b/src/assets/ts/db/notifications.ts new file mode 100644 index 0000000..dc45bff --- /dev/null +++ b/src/assets/ts/db/notifications.ts @@ -0,0 +1,119 @@ +import { randomUUID, type UUID } from 'crypto'; +import { readFile, writeFile } from 'fs/promises'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +interface NotificationItem { + id: UUID; + title: string; + content: string; // md format + date: Date; + read: boolean; + forUserId: string[]; +} + +export class NotificationManager +{ + + private dbPath: string; + + constructor() { + this.dbPath = path.join(__dirname, '../../../../', 'db', 'notifications.json'); + } + + /** + * Read all notifications from the JSON file + */ + private async getAll(): Promise + { + + try { + + const data = await readFile(this.dbPath, 'utf-8'); + + return JSON.parse(data).map((n: any) => ({ + ...n, + date: new Date(n.date) + })); + + } + catch (error) { + return []; + } + + } + + /** + * Save all notifications to the JSON file + */ + private async save(notifications: NotificationItem[]): Promise + { + await writeFile(this.dbPath, JSON.stringify(notifications, null, 2), 'utf-8'); + } + + /** + * Get notifications for a specific user + */ + async getForUser(userId: string): Promise + { + const all = await this.getAll(); + return all.filter(n => n.forUserId.includes(userId)); + } + + /** + * Count unread notifications for today for a specific user + */ + async countTodayUnread(userId: string): Promise + { + + const all = await this.getAll(); + const today = new Date().toLocaleDateString(); + + return all.filter(n => + n.forUserId.includes(userId) && + !n.read && + new Date(n.date).toLocaleDateString() === today + ).length; + + } + + /** + * Add a new notification + */ + async add(notif: Omit): Promise + { + + const all = await this.getAll(); + const newNotif: NotificationItem = { + ...notif, + id: randomUUID(), + date: new Date(), + read: false + }; + + all.push(newNotif); + await this.save(all); + return newNotif; + + } + + /** + * Mark a notification as read + */ + async markAsRead(id: UUID): Promise + { + + const all = await this.getAll(); + const index = all.findIndex(n => n.id === id); + + if (index !== -1) { + all[index].read = true; + await this.save(all); + } + + } + +} \ No newline at end of file From e0a11f0dc6c20251019b6e433c83c2e03d3de5b1 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Wed, 4 Feb 2026 15:18:58 +0100 Subject: [PATCH 14/46] clean --- src/assets/ts/types.ts | 8 -------- src/routes/user.ts | 1 - 2 files changed, 9 deletions(-) diff --git a/src/assets/ts/types.ts b/src/assets/ts/types.ts index 33f1a9c..fc53b12 100644 --- a/src/assets/ts/types.ts +++ b/src/assets/ts/types.ts @@ -7,14 +7,6 @@ export interface User { plan: Plan[]; }; -export interface News { - active: boolean; - message: string; - title: string; - btn: boolean; - href: string; -}; - export interface Layout { all: number; file: number; diff --git a/src/routes/user.ts b/src/routes/user.ts index 0bad1a7..8cc2a3f 100644 --- a/src/routes/user.ts +++ b/src/routes/user.ts @@ -9,7 +9,6 @@ import { User } from '../assets/ts/types.js'; const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!); - // route de gestion de plan router.post('/plan/set', async (req: Request, res: Response) => { From 47e3da331d5a0970b9b13ed5adc2790e55ef027b Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Wed, 4 Feb 2026 15:30:15 +0100 Subject: [PATCH 15/46] add notifications route --- src/assets/ts/db/notifications.ts | 22 +++++++++++++++++----- src/routes/api.ts | 28 +++++++++++++++------------- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/assets/ts/db/notifications.ts b/src/assets/ts/db/notifications.ts index dc45bff..0e3e61b 100644 --- a/src/assets/ts/db/notifications.ts +++ b/src/assets/ts/db/notifications.ts @@ -57,7 +57,7 @@ export class NotificationManager /** * Get notifications for a specific user */ - async getForUser(userId: string): Promise + public async getForUser(userId: string): Promise { const all = await this.getAll(); return all.filter(n => n.forUserId.includes(userId)); @@ -66,7 +66,7 @@ export class NotificationManager /** * Count unread notifications for today for a specific user */ - async countTodayUnread(userId: string): Promise + public async countTodayUnread(userId: string): Promise { const all = await this.getAll(); @@ -83,7 +83,7 @@ export class NotificationManager /** * Add a new notification */ - async add(notif: Omit): Promise + public async add(notif: Omit): Promise { const all = await this.getAll(); @@ -103,9 +103,9 @@ export class NotificationManager /** * Mark a notification as read */ - async markAsRead(id: UUID): Promise + public async markAsRead(id: UUID): Promise { - + const all = await this.getAll(); const index = all.findIndex(n => n.id === id); @@ -116,4 +116,16 @@ export class NotificationManager } + public async getByUserId(userId: string): Promise + { + const all = await this.getAll(); + return all.filter(n => n.forUserId.includes(userId)); + } + +} + +export default new NotificationManager(); + +export { + type NotificationItem } \ No newline at end of file diff --git a/src/routes/api.ts b/src/routes/api.ts index 5f59729..a288fca 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -1,20 +1,13 @@ import { Router, Request, Response } from 'express'; -import { clerkClient } from "@clerk/express"; +import { clerkClient, requireAuth } from "@clerk/express"; import { randomUUID } from 'crypto'; import News from '../assets/ts/news.js'; +import notifications from '../assets/ts/db/notifications.js'; const router = Router(); -router.get('/news', (req: Request, res: Response) => { - - const news = News.getAllNews(); - - res.json(news); - -}) - router.get('/uuid', (req, res) => { res.json({ id: randomUUID() }) }) @@ -36,17 +29,26 @@ router.get('/user/by/id/:userid', async (req, res) => { }) -router.get('/notifications', async (req, res) => { +router.get('/news', (req: Request, res: Response) => { + + const news = News.getAllNews(); + + res.json(news); + +}); + +router.get('/notifications', requireAuth(), async (req: Request, res: Response) => { const client_userId = req.cookies.user_id; if (!client_userId) { - return res.status(401).json({ error: 'Unauthorized' }); + res.status(401).json({ error: 'Unauthorized' }); + return; } - const notifications = await clerkClient.users.getUserNotifications(client_userId); + const notif = await notifications.getByUserId(client_userId); - res.json({ notifications }); + res.json({ notifications: notif }); }); From 0750e8b31f10a29275cd77ff11a12c6aa52e77e0 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Wed, 4 Feb 2026 16:04:41 +0100 Subject: [PATCH 16/46] Create api.notifications.ts --- src/routes/api.notifications.ts | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/routes/api.notifications.ts diff --git a/src/routes/api.notifications.ts b/src/routes/api.notifications.ts new file mode 100644 index 0000000..2e4c067 --- /dev/null +++ b/src/routes/api.notifications.ts @@ -0,0 +1,42 @@ +import { Router, Request, Response } from 'express'; +import { UUID } from 'crypto'; +import notifications from '../assets/ts/db/notifications.js'; + + +const router = Router(); + +router.get('/', async (req: Request, res: Response) => { + + const client_userId = req.cookies.user_id; + + if (!client_userId) { + res.status(401).json({ error: 'Unauthorized' }); + return; + } + + const notif = await notifications.getByUserId(client_userId); + + res.json(notif); + +}); + +router.post('/mark-read/:id', async (req: Request, res: Response) => { + + const client_userId = req.cookies.user_id; + + if (!client_userId) { + res.status(401).json({ error: 'Unauthorized' }); + return; + } + + const notifId: string = req.params.id; + + await notifications.markAsRead(notifId as UUID); + + res.json({ success: true }); + +}); + + + +export default router; From e65ce4ba20a8e45ca847af328f9ec7bd6fc3c8b2 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Wed, 4 Feb 2026 16:04:50 +0100 Subject: [PATCH 17/46] mouve notifications --- src/routes/api.ts | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/routes/api.ts b/src/routes/api.ts index a288fca..411c5c1 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -1,6 +1,6 @@ import { Router, Request, Response } from 'express'; import { clerkClient, requireAuth } from "@clerk/express"; -import { randomUUID } from 'crypto'; +import { randomUUID, UUID } from 'crypto'; import News from '../assets/ts/news.js'; import notifications from '../assets/ts/db/notifications.js'; @@ -37,20 +37,4 @@ router.get('/news', (req: Request, res: Response) => { }); -router.get('/notifications', requireAuth(), async (req: Request, res: Response) => { - - const client_userId = req.cookies.user_id; - - if (!client_userId) { - res.status(401).json({ error: 'Unauthorized' }); - return; - } - - const notif = await notifications.getByUserId(client_userId); - - res.json({ notifications: notif }); - -}); - - export default router; From 0991a2ac7facbf25b45366c64a74be3c24378332 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Wed, 4 Feb 2026 16:04:58 +0100 Subject: [PATCH 18/46] secured routes --- src/express.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/express.ts b/src/express.ts index fa1cfff..8a641c2 100644 --- a/src/express.ts +++ b/src/express.ts @@ -27,6 +27,7 @@ import user from './routes/user.js'; import money from './routes/money.js'; import admin from './routes/admin.js'; import resources from './routes/resources.js'; +import notifications from './routes/api.notifications.js'; const app = express(); const httpServer = createServer(app); @@ -81,13 +82,15 @@ app.use(clerkMiddleware()); // Routes app.use('/api', api); -app.use('/api/share', requireAuth(), api_share); -app.use('/api/ai', api_ai); app.use('/user', user); app.use('/admin', admin); app.use('/money', money); app.use('/resources', resources); +// secured routes +app.use('/api/ai', requireAuth(), api_ai); +app.use('/api/share', requireAuth(), api_share); app.use('/api/db', requireAuth(), api_db); +app.use('/notifications', requireAuth(), notifications); app.get('/version', (req, res) => { From 933e0129186880b27e047aabc357dd67ce3c8992 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Wed, 4 Feb 2026 17:50:29 +0100 Subject: [PATCH 19/46] Update api.notifications.ts --- src/routes/api.notifications.ts | 43 +++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/src/routes/api.notifications.ts b/src/routes/api.notifications.ts index 2e4c067..8230448 100644 --- a/src/routes/api.notifications.ts +++ b/src/routes/api.notifications.ts @@ -1,6 +1,7 @@ import { Router, Request, Response } from 'express'; import { UUID } from 'crypto'; -import notifications from '../assets/ts/db/notifications.js'; +import Notifications from '../assets/ts/db/notifications.js'; +import News from '../assets/ts/news.js'; const router = Router(); @@ -10,13 +11,37 @@ router.get('/', async (req: Request, res: Response) => { const client_userId = req.cookies.user_id; if (!client_userId) { - res.status(401).json({ error: 'Unauthorized' }); + res.status(401).json({ error: true, message: 'UserId cookie not set' }); return; } - const notif = await notifications.getByUserId(client_userId); - - res.json(notif); + const notif = await Notifications.getByUserId(client_userId); + const news = News.getAllNews(); + + let response = [ + ...notif, + ...news + ] + .filter(n => { + + const readers = n.readBy || []; + const isRead = readers.includes(client_userId); + + const notifDate = new Date(n.date).getTime(); + const now = new Date().getTime(); + const oneDayInMs = 24 * 60 * 60 * 1000; + const isOlderThanADay = (now - notifDate) > oneDayInMs; + + return !isRead || !isOlderThanADay; + + }) + .sort((a, b) => { + const dateA = new Date(a.date).getTime(); + const dateB = new Date(b.date).getTime(); + return dateB - dateA; + }); + + res.json(response); }); @@ -25,18 +50,20 @@ router.post('/mark-read/:id', async (req: Request, res: Response) => { const client_userId = req.cookies.user_id; if (!client_userId) { - res.status(401).json({ error: 'Unauthorized' }); + res.status(401).json({ error: true, message: 'UserId cookie not set' }); return; } const notifId: string = req.params.id; - await notifications.markAsRead(notifId as UUID); + await Promise.all([ + Notifications.markAsRead(notifId, client_userId), + News.markNewsAsRead(notifId, client_userId) + ]); res.json({ success: true }); }); - export default router; From 21d3e8e2ca8cc09710bfa8b5d4b2ed9e8cadcb44 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Wed, 4 Feb 2026 17:50:32 +0100 Subject: [PATCH 20/46] Update news.ts --- src/assets/ts/news.ts | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/assets/ts/news.ts b/src/assets/ts/news.ts index b859192..93bb021 100644 --- a/src/assets/ts/news.ts +++ b/src/assets/ts/news.ts @@ -1,20 +1,37 @@ import fs from 'fs'; import path from 'path'; import __dirname from './_dirname.js'; +import { UUID } from 'crypto'; interface NewsItem { - id: number; + id: UUID; title: string; content: string; // md format + readBy: string[]; date: Date; } +const newsFilePath = path.join(__dirname, '../../', 'db', 'news.json'); + + class News { + constructor() + { + if (!fs.existsSync(newsFilePath)) { + fs.writeFileSync(newsFilePath, JSON.stringify([], null, 2), 'utf-8'); + } + } + private getNewsFile (): NewsItem[] { - return JSON.parse(fs.readFileSync(path.join(__dirname, '../config/news.json'), 'utf-8')); + return JSON.parse(fs.readFileSync(newsFilePath, 'utf-8')); + } + + private async saveNewsFile (news: NewsItem[]): Promise + { + await fs.promises.writeFile(newsFilePath, JSON.stringify(news, null, 2), 'utf-8'); } public getAllNews (): NewsItem[] @@ -28,6 +45,21 @@ class News return news.slice(0, count); } + public async markNewsAsRead (newsId: string, userId: string): Promise + { + + const news = this.getNewsFile(); + const index = news.findIndex(n => n.id === newsId); + + if (index !== -1) { + if (news[index].readBy.includes(userId)) return; + news[index].readBy.push(userId); + console.log(`User ${userId} marked news ${newsId} as read, ${news[index].readBy.length} total reads.`); + await this.saveNewsFile(news); + } + + } + } export default new News(); From 3b31b9ca7adfecba32c80b55de228be7c60db638 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Wed, 4 Feb 2026 17:50:35 +0100 Subject: [PATCH 21/46] Update notifications.ts --- src/assets/ts/db/notifications.ts | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/assets/ts/db/notifications.ts b/src/assets/ts/db/notifications.ts index 0e3e61b..46171d5 100644 --- a/src/assets/ts/db/notifications.ts +++ b/src/assets/ts/db/notifications.ts @@ -1,18 +1,27 @@ import { randomUUID, type UUID } from 'crypto'; import { readFile, writeFile } from 'fs/promises'; import path from 'path'; +import fs from 'fs'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); + +interface Btn { + text: string; + action: string, // () => void + type: 'default-primary' | 'primary' | 'primary danger' +}; + interface NotificationItem { id: UUID; title: string; content: string; // md format date: Date; - read: boolean; + readBy: string[]; forUserId: string[]; + btns?: Btn[]; } export class NotificationManager @@ -21,7 +30,8 @@ export class NotificationManager private dbPath: string; constructor() { - this.dbPath = path.join(__dirname, '../../../../', 'db', 'notifications.json'); + this.dbPath = path.join(__dirname, '../../../', 'db', 'notifications.json'); + if (!fs.existsSync(this.dbPath)) fs.writeFileSync(this.dbPath, JSON.stringify([]), 'utf-8'); } /** @@ -33,8 +43,9 @@ export class NotificationManager try { const data = await readFile(this.dbPath, 'utf-8'); + const parseData: NotificationItem[] = JSON.parse(data); - return JSON.parse(data).map((n: any) => ({ + return parseData.map((n: any) => ({ ...n, date: new Date(n.date) })); @@ -74,7 +85,7 @@ export class NotificationManager return all.filter(n => n.forUserId.includes(userId) && - !n.read && + !n.readBy.includes(userId) && new Date(n.date).toLocaleDateString() === today ).length; @@ -83,7 +94,7 @@ export class NotificationManager /** * Add a new notification */ - public async add(notif: Omit): Promise + public async add(notif: Omit): Promise { const all = await this.getAll(); @@ -91,7 +102,7 @@ export class NotificationManager ...notif, id: randomUUID(), date: new Date(), - read: false + readBy: [] }; all.push(newNotif); @@ -103,14 +114,15 @@ export class NotificationManager /** * Mark a notification as read */ - public async markAsRead(id: UUID): Promise + public async markAsRead(id: string, user_id: string): Promise { const all = await this.getAll(); const index = all.findIndex(n => n.id === id); if (index !== -1) { - all[index].read = true; + if (all[index].readBy.includes(user_id)) return; + all[index].readBy.push(user_id); await this.save(all); } From edbdadd2318fce6936f41f084372372e9a3f5822 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Wed, 4 Feb 2026 17:50:42 +0100 Subject: [PATCH 22/46] Delete news.json --- src/assets/config/news.json | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 src/assets/config/news.json diff --git a/src/assets/config/news.json b/src/assets/config/news.json deleted file mode 100644 index 1935949..0000000 --- a/src/assets/config/news.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "id": 1, - "title": "Nouvelle mise à jour disponible !", - "content": "## Version 1.5 est là !\n\nNous avons ajouté plusieurs améliorations :\n- Mode sombre pour vos notes 🌙\n- Recherche plus rapide 🔍\n- Correction de bugs mineurs 🐞\n\nMettez à jour pour profiter de ces nouveautés !", - "date": "2026-02-04T09:00:00Z" - }, - { - "id": 2, - "title": "Astuce du jour : organiser vos notes", - "content": "### Classez vos notes par tags\n\nUtilisez des **tags** pour mieux organiser vos notes et retrouver vos idées en un clin d'œil.\n\nExemple :\n- `#travail`\n- `#personnel`\n- `#projets`", - "date": "2026-02-03T14:30:00Z" - }, - { - "id": 3, - "title": "Mini-jeux intégrés à Silvernote !", - "content": "Pour rendre vos pauses plus fun, nous avons ajouté **des mini-jeux** :\n- 🐍 Snake\n- 🔢 2048\n- 🧩 Puzzle rapide\n\nAccédez à eux depuis le menu **Divertissement** !", - "date": "2026-02-02T10:15:00Z" - }, - { - "id": 4, - "title": "Synchronisation cloud améliorée", - "content": "La synchronisation de vos notes avec le cloud est **plus rapide et fiable**.\n\n- Synchronisation automatique en arrière-plan ☁️\n- Moins de conflits entre appareils\n- Historique de versions amélioré 📜", - "date": "2026-02-01T08:45:00Z" - }, - { - "id": 5, - "title": "Partage de notes simplifié", - "content": "Vous pouvez maintenant **partager vos notes** avec vos amis ou collègues en un clic :\n\n- Générez un lien public 🌐\n- Définissez les permissions (lecture seule ou modification)\n- Partage rapide via email ou messagerie 📧", - "date": "2026-01-31T16:00:00Z" - } -] From dbbe395708222803a77d8261affcaa1963805d81 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Wed, 4 Feb 2026 17:51:03 +0100 Subject: [PATCH 23/46] mouve news routes to /api/notifications --- src/routes/api.ts | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/routes/api.ts b/src/routes/api.ts index 411c5c1..6289a01 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -1,18 +1,16 @@ import { Router, Request, Response } from 'express'; -import { clerkClient, requireAuth } from "@clerk/express"; +import { clerkClient } from "@clerk/express"; import { randomUUID, UUID } from 'crypto'; -import News from '../assets/ts/news.js'; -import notifications from '../assets/ts/db/notifications.js'; const router = Router(); -router.get('/uuid', (req, res) => { +router.get('/uuid', (req: Request, res: Response) => { res.json({ id: randomUUID() }) }) -router.get('/user/by/id/:userid', async (req, res) => { +router.get('/user/by/id/:userid', async (req: Request, res: Response) => { const userid: string = req.params.userid; const client_userId = req.cookies.user_id; @@ -28,13 +26,4 @@ router.get('/user/by/id/:userid', async (req, res) => { }) - -router.get('/news', (req: Request, res: Response) => { - - const news = News.getAllNews(); - - res.json(news); - -}); - export default router; From d05b61b722b0f9287ab3c91eff87424df51956a9 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Wed, 4 Feb 2026 17:51:26 +0100 Subject: [PATCH 24/46] Update express.ts --- src/express.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/express.ts b/src/express.ts index 8a641c2..93c7cc8 100644 --- a/src/express.ts +++ b/src/express.ts @@ -90,7 +90,7 @@ app.use('/resources', resources); app.use('/api/ai', requireAuth(), api_ai); app.use('/api/share', requireAuth(), api_share); app.use('/api/db', requireAuth(), api_db); -app.use('/notifications', requireAuth(), notifications); +app.use('/api/notifications', requireAuth(), notifications); app.get('/version', (req, res) => { From af3125d60a0b05c05f4b93ecb508fc744c3247bf Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Thu, 5 Feb 2026 09:33:12 +0100 Subject: [PATCH 25/46] add android token support --- src/assets/ts/database.ts | 32 ++++++++++++++++++++++ src/assets/ts/types.ts | 1 + src/routes/api.notifications.ts | 48 ++++++++++++++++++++++++++++++++- 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/src/assets/ts/database.ts b/src/assets/ts/database.ts index d03eb1d..e14f89c 100644 --- a/src/assets/ts/database.ts +++ b/src/assets/ts/database.ts @@ -69,7 +69,39 @@ class Database { } + public setAndroidToken ( userID: string, token: string ): Promise { + return new Promise( async (resolve, reject) => { + + try { + + const db: User[] = await this.get('user'); + + const userIndex = db.findIndex(user => user.userId === userID); + + if (userIndex === -1) { + throw new Error('Utilisateur non trouvé'); + } + + if (!db[userIndex].androidToken) { + db[userIndex].androidToken = ''; + } + + if (db[userIndex].androidToken !== token) { + db[userIndex].androidToken = token; + } + + await this.save('user', db); + + resolve(); + + } catch (error) { + reject(error); + } + + }); + + } public async new_session ( userID: string ): Promise { diff --git a/src/assets/ts/types.ts b/src/assets/ts/types.ts index fc53b12..558d16c 100644 --- a/src/assets/ts/types.ts +++ b/src/assets/ts/types.ts @@ -4,6 +4,7 @@ import { Plan } from "./plan.js"; export interface User { userId: string; customerId?: string; + androidToken?: string; plan: Plan[]; }; diff --git a/src/routes/api.notifications.ts b/src/routes/api.notifications.ts index 8230448..04e09e6 100644 --- a/src/routes/api.notifications.ts +++ b/src/routes/api.notifications.ts @@ -1,7 +1,7 @@ import { Router, Request, Response } from 'express'; -import { UUID } from 'crypto'; import Notifications from '../assets/ts/db/notifications.js'; import News from '../assets/ts/news.js'; +import database from '../assets/ts/database.js'; const router = Router(); @@ -66,4 +66,50 @@ router.post('/mark-read/:id', async (req: Request, res: Response) => { }); +// android notifications + +router.post('/android/register', async (req: Request, res: Response) => { + + const client_userId = req.cookies.user_id; + const { fcm_token } = req.body; + + if (!client_userId) { + res.status(401).json({ error: true, message: 'UserId cookie not set' }); + return; + } + + if (!fcm_token) { + res.status(400).json({ error: true, message: 'fcm_token is required' }); + return; + } + + await database.setAndroidToken(client_userId, fcm_token); + + res.json({ success: true }); + +}); + +router.post('/android/unregister', async (req: Request, res: Response) => { + + const client_userId = req.cookies.user_id; + const { fcm_token } = req.body; + + if (!client_userId) { + res.status(401).json({ error: true, message: 'UserId cookie not set' }); + return; + } + + if (!fcm_token) { + res.status(400).json({ error: true, message: 'fcm_token is required' }); + return; + } + + await database.setAndroidToken(client_userId, 'none'); + + res.json({ success: true }); + +}); + + + export default router; From a6591017650ac1a9bf32289a8bfff12392e1f2b2 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Thu, 5 Feb 2026 09:33:45 +0100 Subject: [PATCH 26/46] create 2048 api --- src/express.ts | 2 ++ src/mcp-server/src/tools/edit_note_content.ts | 5 ----- src/routes/api.2048.ts | 11 +++++++++++ 3 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 src/routes/api.2048.ts diff --git a/src/express.ts b/src/express.ts index 93c7cc8..d469194 100644 --- a/src/express.ts +++ b/src/express.ts @@ -28,6 +28,7 @@ import money from './routes/money.js'; import admin from './routes/admin.js'; import resources from './routes/resources.js'; import notifications from './routes/api.notifications.js'; +import api_2048 from './routes/api.2048.js'; const app = express(); const httpServer = createServer(app); @@ -91,6 +92,7 @@ app.use('/api/ai', requireAuth(), api_ai); app.use('/api/share', requireAuth(), api_share); app.use('/api/db', requireAuth(), api_db); app.use('/api/notifications', requireAuth(), notifications); +app.use('/api/2048', requireAuth(), api_2048); app.get('/version', (req, res) => { diff --git a/src/mcp-server/src/tools/edit_note_content.ts b/src/mcp-server/src/tools/edit_note_content.ts index 990b116..9fa6182 100644 --- a/src/mcp-server/src/tools/edit_note_content.ts +++ b/src/mcp-server/src/tools/edit_note_content.ts @@ -1,11 +1,6 @@ import { Tool } from "../../MCPTypes.js"; import useWS from "../utils/useWS.js"; import { z } from "zod"; -import * as Y from "yjs"; -import { JSDOM } from "jsdom"; -import schema from "../../../assets/ts/utils/getTiptapSchema/getTiptapSchema.js"; -import { DOMParser } from "prosemirror-model"; -import { prosemirrorToYXmlFragment } from "y-prosemirror"; const edit_note_content: Tool = { diff --git a/src/routes/api.2048.ts b/src/routes/api.2048.ts new file mode 100644 index 0000000..d61ec0a --- /dev/null +++ b/src/routes/api.2048.ts @@ -0,0 +1,11 @@ +import { Router, Request, Response } from 'express'; + + +const router = Router(); + + + + + + +export default router; From 9ac86ef5e25a8c28f68349e4ac7e2a92283cdda7 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Thu, 5 Feb 2026 10:03:34 +0100 Subject: [PATCH 27/46] Create 2048_db.ts --- src/assets/ts/db/2048_db.ts | 170 ++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 src/assets/ts/db/2048_db.ts diff --git a/src/assets/ts/db/2048_db.ts b/src/assets/ts/db/2048_db.ts new file mode 100644 index 0000000..78b683f --- /dev/null +++ b/src/assets/ts/db/2048_db.ts @@ -0,0 +1,170 @@ +import { readFile, writeFile } from 'fs/promises'; +import path from 'path'; +import fs from 'fs'; +import { fileURLToPath } from 'url'; + + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + + +interface UserItem { + id: string; + best_score: number; + total_score: number; + max_tile: number; + lastPlayed: Date | null; + partiesCount: number; +} + +interface UserItemSmall { + id: string; + best_score: number; + max_tile: number; + lastPlayed: Date | null; +} + + + +export class GameManager +{ + + private dbPath: string; + + constructor() + { + + const dbDir = path.join(__dirname, '../../../', 'db'); + this.dbPath = path.join(dbDir, '2048.json'); + + if (!fs.existsSync(dbDir)) { + fs.mkdirSync(dbDir, { recursive: true }); + } + + if (!fs.existsSync(this.dbPath)) { + fs.writeFileSync(this.dbPath, JSON.stringify([]), 'utf-8'); + } + + } + + public async getAll(): Promise + { + + try { + + const data = await readFile(this.dbPath, 'utf-8'); + const users: UserItem[] = JSON.parse(data); + + return users.map(user => ({ + ...user, + lastPlayed: user.lastPlayed ? new Date(user.lastPlayed) : null + })); + + } + catch (error) { + console.error("Erreur lecture 2048.json:", error); + return []; + } + + } + + public async getByUserID(userId: string): Promise + { + + const users = await this.getAll(); + const user = users.find(u => u.id === userId); + + if (user) return user; + + const newUser: UserItem = { + id: userId, + best_score: 0, + total_score: 0, + max_tile: 0, + lastPlayed: null, + partiesCount: 0 + }; + + users.push(newUser); + await this.saveAll(users); + + return newUser; + + } + + + public async update(rawUpdate: UserItemSmall): Promise + { + + let existingUser = await this.getByUserID(rawUpdate.id); + + if (!existingUser) + { + existingUser = await this.create(rawUpdate.id); + } + + const update: UserItem = { + id: rawUpdate.id, + best_score: rawUpdate.best_score > existingUser.best_score ? rawUpdate.best_score : existingUser.best_score, + total_score: existingUser.total_score + rawUpdate.best_score, + max_tile: rawUpdate.max_tile > existingUser.max_tile ? rawUpdate.max_tile : existingUser.max_tile, + lastPlayed: rawUpdate.lastPlayed || new Date(), + partiesCount: existingUser.partiesCount + 1 + }; + + const users = await this.getAll(); + const index = users.findIndex(u => u.id === update.id); + + if (index !== -1) { + users[index] = { ...update }; + } else { + users.push(update); + } + + await this.saveAll(users); + + } + + public async create(userId: string): Promise + { + + const users = await this.getAll(); + const existingUser = users.find(u => u.id === userId); + + if (existingUser) { + return existingUser; + } + + const newUser: UserItem = { + id: userId, + best_score: 0, + total_score: 0, + max_tile: 0, + lastPlayed: null, + partiesCount: 0 + }; + + users.push(newUser); + await this.saveAll(users); + + return newUser; + + } + + + private async saveAll(users: UserItem[]): Promise + { + try { + await writeFile(this.dbPath, JSON.stringify(users, null, 2), 'utf-8'); + } catch (error) { + console.error("Erreur écriture 2048.json:", error); + } + } + +} + +export default new GameManager(); + +export { + type UserItem +}; \ No newline at end of file From ecd2627060e95817d61fe0c68b9adcae68f0273f Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Thu, 5 Feb 2026 10:03:37 +0100 Subject: [PATCH 28/46] Update api.2048.ts --- src/routes/api.2048.ts | 100 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/src/routes/api.2048.ts b/src/routes/api.2048.ts index d61ec0a..d9df460 100644 --- a/src/routes/api.2048.ts +++ b/src/routes/api.2048.ts @@ -1,10 +1,110 @@ import { Router, Request, Response } from 'express'; +import GameManager from '../assets/ts/db/2048_db.js'; const router = Router(); +router.post('/update', async (req: Request, res: Response) => { + const data = req.body.data; + + if (!data || !data.id) + { + res.status(400).json({ + error: true, + message: "Données invalides", + received: req.body, + need: { + id: "string", + best_score: "number", + max_tile: "number", + lastPlayed: "Date", + } + }); + return; + } + + try { + + GameManager.update(data); + res.json({ success: true }); + + } + catch (error) { + res.status(500).json({ + error: true, + message: "Erreur serveur", + details: error + }); + } + +}); + + +router.get('/leaderboard', async (req: Request, res: Response) => { + + try { + + const allPlayers = await GameManager.getAll(); + + const sortedByBestScore = [...allPlayers].sort((a, b) => b.best_score - a.best_score); + const sortedByTotalScore = [...allPlayers].sort((a, b) => b.total_score - a.total_score); + const sortedByMaxTile = [...allPlayers].sort((a, b) => b.max_tile - a.max_tile); + + res.json({ + success: true, + leaderboard: { + best_score: sortedByBestScore, + total_score: sortedByTotalScore, + max_tile: sortedByMaxTile + } + }); + + } + catch (error) { + res.status(500).json({ + error: true, + message: "Erreur serveur", + details: error + }); + } + +}); + + +router.get('/player/:id', async (req: Request, res: Response) => { + + const playerId = req.cookies.userId; + + try { + + const playerData = await GameManager.getByUserID(playerId); + + if (!playerData) { + res.status(404).json({ + error: true, + message: "Joueur non trouvé", + playerId + }); + return; + } + + res.json({ + success: true, + player: playerData + }); + + } + catch (error) { + res.status(500).json({ + error: true, + message: "Erreur serveur", + details: error + }); + } + +}); From c596003bd9e728bec1c7c5624c64dcd1b1d77fe9 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Thu, 5 Feb 2026 10:12:48 +0100 Subject: [PATCH 29/46] Update api.2048.ts --- src/routes/api.2048.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/api.2048.ts b/src/routes/api.2048.ts index d9df460..362ef42 100644 --- a/src/routes/api.2048.ts +++ b/src/routes/api.2048.ts @@ -75,7 +75,7 @@ router.get('/leaderboard', async (req: Request, res: Response) => { router.get('/player/:id', async (req: Request, res: Response) => { - const playerId = req.cookies.userId; + const playerId = req.params.id; try { From da6299f4eaeb5d545b4deb74fe042a15a450361c Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Thu, 5 Feb 2026 14:08:24 +0100 Subject: [PATCH 30/46] fix 2048 api --- src/assets/ts/db/2048_db.ts | 2 +- src/routes/api.2048.ts | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/assets/ts/db/2048_db.ts b/src/assets/ts/db/2048_db.ts index 78b683f..c4672c9 100644 --- a/src/assets/ts/db/2048_db.ts +++ b/src/assets/ts/db/2048_db.ts @@ -106,7 +106,7 @@ export class GameManager const update: UserItem = { id: rawUpdate.id, best_score: rawUpdate.best_score > existingUser.best_score ? rawUpdate.best_score : existingUser.best_score, - total_score: existingUser.total_score + rawUpdate.best_score, + total_score: existingUser.total_score + rawUpdate.best_score, // best score = score max_tile: rawUpdate.max_tile > existingUser.max_tile ? rawUpdate.max_tile : existingUser.max_tile, lastPlayed: rawUpdate.lastPlayed || new Date(), partiesCount: existingUser.partiesCount + 1 diff --git a/src/routes/api.2048.ts b/src/routes/api.2048.ts index 362ef42..a02118d 100644 --- a/src/routes/api.2048.ts +++ b/src/routes/api.2048.ts @@ -76,6 +76,18 @@ router.get('/leaderboard', async (req: Request, res: Response) => { router.get('/player/:id', async (req: Request, res: Response) => { const playerId = req.params.id; + const userId = req.cookies.userId; + + if (playerId !== userId) + { + res.status(403).json({ + error: true, + message: "Accès refusé : vous ne pouvez accéder qu'à vos propres données", + playerId, + userId + }); + return; + } try { From 41b4a2e58f1dd1edc5040290b451e999f9e31841 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Fri, 6 Feb 2026 12:04:12 +0100 Subject: [PATCH 31/46] Create userDB.ts --- src/assets/ts/db/userDB.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/assets/ts/db/userDB.ts diff --git a/src/assets/ts/db/userDB.ts b/src/assets/ts/db/userDB.ts new file mode 100644 index 0000000..6637a5e --- /dev/null +++ b/src/assets/ts/db/userDB.ts @@ -0,0 +1,11 @@ +import https from 'https'; + +const dbAgent = new https.Agent({ + keepAlive: true, + maxSockets: 100, + timeout: 60000 +}); + +export { + dbAgent +} \ No newline at end of file From b8ce33cebd3f254c1822deef9d1f4f2f23bada02 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Fri, 6 Feb 2026 12:04:25 +0100 Subject: [PATCH 32/46] sync with new db --- src/assets/ts/notes.ts | 42 +++++++++++++++++++++++++++++++++++++----- src/assets/ts/tags.ts | 2 ++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/assets/ts/notes.ts b/src/assets/ts/notes.ts index 7649d5a..4b01d09 100644 --- a/src/assets/ts/notes.ts +++ b/src/assets/ts/notes.ts @@ -1,6 +1,7 @@ import nodeFetch from 'node-fetch'; import type { Note } from "./types.js"; import { randomUUID } from "crypto"; +import { dbAgent } from './db/userDB.js'; import 'dotenv/config'; import { decrypt, encrypt } from './utils/scrypto/scrypto.js'; @@ -35,6 +36,7 @@ import { decrypt, encrypt } from './utils/scrypto/scrypto.js'; const res = await nodeFetch('https://db.silvernote.fr/notes' + path, { method: opt.method || 'GET', body: opt.body, + agent: dbAgent, headers: { "Authorization": process.env.DB_API_SK_1 || "", "X-API-Key": process.env.DB_API_SK_2 || "", @@ -80,9 +82,9 @@ import { decrypt, encrypt } from './utils/scrypto/scrypto.js'; } - public async getNoteByUUID(uuid: string) { + public async getNoteByUUID(uuid: string, userId: string) { - const res: Note[] = await this.fetch(`/get/${uuid}`); + const res: Note[] = await this.fetch(`/user/${userId}/id/${uuid}`).then(res => res.notes); const note: Note = res[0]; @@ -124,7 +126,7 @@ import { decrypt, encrypt } from './utils/scrypto/scrypto.js'; public async getNoteByUserId(user_id: string) { - const notes: Note[] = await this.fetch(`/get/byuserid/${user_id}`); + const notes: Note[] = await this.fetch(`/user/${user_id}`).then(res => res.notes); const decryptedNotes: Note[] = []; for (const note of notes) @@ -152,6 +154,36 @@ import { decrypt, encrypt } from './utils/scrypto/scrypto.js'; } + public async getNoteByUserIdIndex(user_id: string, start: number, end: number) { + + const res = await this.fetch(`/user/${user_id}/index/start/${start}/end/${end}`); + const decryptedNotes: Note[] = []; + + for (const note of res.notes) + { + + if (note.content_type === "text/html/crypted" && note.content) + { + + try { + note.content = decrypt(note.content, note.user_id); + decryptedNotes.push(note); + } catch (e) { + console.error("Error on decrypting note : ", note.uuid); + } + + } + else + { + decryptedNotes.push(note); + } + + } + + return { success: true, notes: decryptedNotes }; + + } + public async updateNote(note: Note) { if (!note.uuid || !note.user_id) { @@ -182,7 +214,7 @@ import { decrypt, encrypt } from './utils/scrypto/scrypto.js'; } public async clearUserNotes(user_id: string) { - await this.fetch('/delete/byuserid/' + user_id, { + await this.fetch('/delete/user/' + user_id, { method: 'DELETE' }) return { success: true }; @@ -190,7 +222,7 @@ import { decrypt, encrypt } from './utils/scrypto/scrypto.js'; public async deleteNoteByUUID(user_id: string, uuid: string) { - const res = await this.fetch('/delete/' + uuid, { + const res = await this.fetch(`/delete/user/${user_id}/id/${uuid}`, { method: "DELETE" }) diff --git a/src/assets/ts/tags.ts b/src/assets/ts/tags.ts index a1f9765..c6bc112 100644 --- a/src/assets/ts/tags.ts +++ b/src/assets/ts/tags.ts @@ -1,6 +1,7 @@ import nodeFetch from 'node-fetch'; import type { Tag } from "./types.js"; import { randomUUID } from "crypto"; +import { dbAgent } from './db/userDB.js'; class Tags { @@ -34,6 +35,7 @@ import { randomUUID } from "crypto"; { const res = await nodeFetch('https://db.silvernote.fr/tags' + path, { ...opt, + agent: dbAgent, headers: { "Authorization": process.env.DB_API_SK_1 || "", "X-API-Key": process.env.DB_API_SK_2 || "", From b289b86424dde6882742dcaea5e885e3e291f8c6 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Fri, 6 Feb 2026 12:04:31 +0100 Subject: [PATCH 33/46] Update api.db.ts --- src/routes/api.db.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/routes/api.db.ts b/src/routes/api.db.ts index 85df0ca..6586106 100644 --- a/src/routes/api.db.ts +++ b/src/routes/api.db.ts @@ -81,7 +81,7 @@ router.post('/new/note', async (req: Request, res: Response) => { }); router.get('/get/a/note', async (req: Request, res: Response) => { - res.json(await note_db.getNoteByUUID(req.query.uuid as string)); + res.json(await note_db.getNoteByUUID(req.query.uuid as string, req.cookies.user_id)); }); router.post('/update/a/note', async (req: Request, res: Response) => { @@ -94,10 +94,13 @@ router.post('/delete/a/note', async (req: Request, res: Response) => { res.json(await note_db.deleteNoteByUUID(req.cookies.user_id, req.query.uuid as string)); }); -router.get('/get/user/notes', async (req: Request, res: Response) => { +router.get('/notes/start/:start/end/:end', async (req: Request, res: Response) => { - const userId = req.query.user_id as string; - const db_res = await note_db.getNoteByUserId(userId); + const userId = String(req.cookies.userId); + const start = Number(req.params.start); + const end = Number(req.params.end); + + const db_res = await note_db.getNoteByUserIdIndex(userId, start, end); res.json({ ...db_res, From 3203f48f391f5f1bf65deff1215c133e9d349d58 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Fri, 6 Feb 2026 12:15:45 +0100 Subject: [PATCH 34/46] get user id with clerk auth --- src/routes/api.db.ts | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/routes/api.db.ts b/src/routes/api.db.ts index 6586106..e46e723 100644 --- a/src/routes/api.db.ts +++ b/src/routes/api.db.ts @@ -12,6 +12,7 @@ import FormData from "form-data"; import downloadFile from "../assets/ts/downloadFile.js"; import { fileURLToPath } from "url"; import { getUserFingerprint } from "../assets/ts/utils/scrypto/scrypto.js"; +import { getAuth } from "@clerk/express"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -24,7 +25,7 @@ router.post('/verify/data', async (req: Request, res: Response) => { try { const { notes, tags } = req.body as { notes: string; tags: string }; // hash of notes and tags - const user_id: string | undefined = req.cookies?.user_id; + const user_id = getAuth(req).userId; if (!notes || !tags || !user_id) { res.json({ error: true, message: 'Missing parameters.' }); @@ -59,13 +60,9 @@ router.post('/verify/data', async (req: Request, res: Response) => { router.get('/get/scrypto/fingerprint', async (req: Request, res: Response) => { - const userId = req.cookies.user_id; - if (!userId) { - res.status(400).json({ error: true, message: 'user_id cookie is required.' }); - return; - } + const userId = getAuth(req).userId; - const fingerprint = getUserFingerprint(userId); + const fingerprint = getUserFingerprint(userId!); res.json({ fingerprint }); @@ -75,28 +72,32 @@ router.get('/get/scrypto/fingerprint', async (req: Request, res: Response) => { // for notes router.post('/new/note', async (req: Request, res: Response) => { + const { userId } = getAuth(req); const note = req.body.note; - note.user_id = req.cookies.user_id; + note.user_id = userId; res.json(await note_db.createNote(note)); }); router.get('/get/a/note', async (req: Request, res: Response) => { - res.json(await note_db.getNoteByUUID(req.query.uuid as string, req.cookies.user_id)); + const user_id = getAuth(req).userId; + res.json(await note_db.getNoteByUUID(req.query.uuid as string, user_id!)); }); router.post('/update/a/note', async (req: Request, res: Response) => { const note = req.body.note; - note.user_id = req.cookies.user_id; + const user_id = getAuth(req).userId; + note.user_id = user_id; res.json(await note_db.updateNote(note)); }); router.post('/delete/a/note', async (req: Request, res: Response) => { - res.json(await note_db.deleteNoteByUUID(req.cookies.user_id, req.query.uuid as string)); + const user_id = getAuth(req).userId; + res.json(await note_db.deleteNoteByUUID(user_id!, req.query.uuid as string)); }); router.get('/notes/start/:start/end/:end', async (req: Request, res: Response) => { - const userId = String(req.cookies.userId); + const userId = String(getAuth(req).userId); const start = Number(req.params.start); const end = Number(req.params.end); @@ -120,7 +121,8 @@ router.get('/notes/start/:start/end/:end', async (req: Request, res: Response) = }); router.post('/delete/notes', async (req: Request, res: Response) => { - res.json(await note_db.clearUserNotes(req.cookies.user_id)); + const user_id = getAuth(req).userId; + res.json(await note_db.clearUserNotes(user_id!)); }); @@ -128,18 +130,21 @@ router.post('/delete/notes', async (req: Request, res: Response) => { // for tags router.post('/new/tag', async (req: Request, res: Response) => { const tag = req.body.tag; - tag.user_id = req.cookies.user_id; + const user_id = getAuth(req).userId; + tag.user_id = user_id!; res.json(await tag_db.createTag(tag)); }); router.post('/update/a/tag', async (req: Request, res: Response) => { const tag = req.body.tag; - tag.user_id = req.cookies.user_id; + const user_id = getAuth(req).userId; + tag.user_id = user_id!; res.json(await tag_db.updateTag(tag)); }); router.post('/delete/a/tag', async (req: Request, res: Response) => { - res.json(await tag_db.deleteTagByUUID(req.cookies.user_id, String(req.query.uuid))); + const user_id = getAuth(req).userId; + res.json(await tag_db.deleteTagByUUID(user_id!, String(req.query.uuid))); }); router.get('/get/user/tags', async (req: Request, res: Response) => { @@ -147,7 +152,8 @@ router.get('/get/user/tags', async (req: Request, res: Response) => { }); router.post('/delete/tags', async (req: Request, res: Response) => { - res.json(await tag_db.clearUserTags(req.cookies.user_id)); + const user_id = getAuth(req).userId; + res.json(await tag_db.clearUserTags(user_id!)); }); From ab0e2135a8f27e56c4ecfd0f5c8e745dfe9bfb23 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Fri, 6 Feb 2026 12:24:38 +0100 Subject: [PATCH 35/46] add get pinned notes --- src/assets/ts/notes.ts | 32 +++++++++++++++++++++++++++++++- src/routes/api.db.ts | 17 +++++++++++++++-- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/assets/ts/notes.ts b/src/assets/ts/notes.ts index 4b01d09..9cc8a05 100644 --- a/src/assets/ts/notes.ts +++ b/src/assets/ts/notes.ts @@ -124,6 +124,36 @@ import { decrypt, encrypt } from './utils/scrypto/scrypto.js'; } + public async getPinnedNotesByUserID (user_id: string) + { + + const notes: Note[] = await this.fetch(`/user/${user_id}/pinned`).then(res => res.notes); + const decryptedNotes: Note[] = []; + + for (const note of notes) + { + + if (note.content_type === "text/html/crypted" && note.content) + { + + try { + note.content = decrypt(note.content, note.user_id); + decryptedNotes.push(note); + } catch (e) { + console.error("Error on decrypting note : ", note.uuid); + } + + } + else + { + decryptedNotes.push(note); + } + + } + + return { success: true, notes: decryptedNotes }; + } + public async getNoteByUserId(user_id: string) { const notes: Note[] = await this.fetch(`/user/${user_id}`).then(res => res.notes); @@ -180,7 +210,7 @@ import { decrypt, encrypt } from './utils/scrypto/scrypto.js'; } - return { success: true, notes: decryptedNotes }; + return { ...res, success: true, notes: decryptedNotes }; } diff --git a/src/routes/api.db.ts b/src/routes/api.db.ts index e46e723..23db102 100644 --- a/src/routes/api.db.ts +++ b/src/routes/api.db.ts @@ -105,11 +105,11 @@ router.get('/notes/start/:start/end/:end', async (req: Request, res: Response) = res.json({ ...db_res, - notes: db_res.notes.filter(note => note.title !== '' || note.content !== '') + notes: db_res.notes }); // identify gost notes - const ghostNotes: Note[] = db_res.notes.filter(note => + const ghostNotes: Note[] = db_res.notes.filter((note: Note) => note.title === '' && note.content === '' || note.title === '' && note.content === '

' ); @@ -120,6 +120,19 @@ router.get('/notes/start/:start/end/:end', async (req: Request, res: Response) = }); +router.get('/notes/pinned', async (req, res) => { + + const userId = String(getAuth(req).userId); + + const db_res = await note_db.getPinnedNotesByUserID(userId); + + res.json({ + ...db_res, + notes: db_res.notes + }); + +}) + router.post('/delete/notes', async (req: Request, res: Response) => { const user_id = getAuth(req).userId; res.json(await note_db.clearUserNotes(user_id!)); From fc72e7c30362c2549f7ded5782bf66664a42ab35 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Fri, 6 Feb 2026 12:42:21 +0100 Subject: [PATCH 36/46] add noPinnned --- src/assets/ts/notes.ts | 4 ++-- src/routes/api.db.ts | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/assets/ts/notes.ts b/src/assets/ts/notes.ts index 9cc8a05..0005a7b 100644 --- a/src/assets/ts/notes.ts +++ b/src/assets/ts/notes.ts @@ -184,9 +184,9 @@ import { decrypt, encrypt } from './utils/scrypto/scrypto.js'; } - public async getNoteByUserIdIndex(user_id: string, start: number, end: number) { + public async getNoteByUserIdIndex(user_id: string, start: number, end: number, noPinned?: '1' | '0') { - const res = await this.fetch(`/user/${user_id}/index/start/${start}/end/${end}`); + const res = await this.fetch(`/user/${user_id}/index/start/${start}/end/${end}?noPinned=${noPinned}`); const decryptedNotes: Note[] = []; for (const note of res.notes) diff --git a/src/routes/api.db.ts b/src/routes/api.db.ts index 23db102..46edb47 100644 --- a/src/routes/api.db.ts +++ b/src/routes/api.db.ts @@ -97,11 +97,12 @@ router.post('/delete/a/note', async (req: Request, res: Response) => { router.get('/notes/start/:start/end/:end', async (req: Request, res: Response) => { + const noPinned = String(req.query?.noPinned || '0') as '1' | '0'; const userId = String(getAuth(req).userId); const start = Number(req.params.start); const end = Number(req.params.end); - const db_res = await note_db.getNoteByUserIdIndex(userId, start, end); + const db_res = await note_db.getNoteByUserIdIndex(userId, start, end, noPinned); res.json({ ...db_res, From a51c13ed1a845985081f872e4c36a45d00f6d20f Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Fri, 6 Feb 2026 12:52:51 +0100 Subject: [PATCH 37/46] get user id by clerk auth for share --- src/routes/api.share.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/routes/api.share.ts b/src/routes/api.share.ts index 020ce9c..a63774d 100644 --- a/src/routes/api.share.ts +++ b/src/routes/api.share.ts @@ -2,6 +2,7 @@ import { Router } from 'express'; import type { Note } from '../assets/ts/types.js'; import notes from '../assets/ts/notes.js'; import Share from '../assets/ts/db/share/index.js'; +import { getAuth } from '@clerk/express'; const router = Router(); @@ -11,7 +12,8 @@ router.get('/:uuid', async (req, res) => { const { uuid } = req.params; const passwd = req.query.passwd; - const visitor_userid = req.cookies.user_id; + const visitor_userid = getAuth(req).userId; + if (!visitor_userid) return; const TheShare = await Share.get(uuid); @@ -42,7 +44,7 @@ router.get('/:uuid', async (req, res) => { return; } - const note = await notes.getNoteByUUID(TheShare.note_uuid); + const note = await notes.getNoteByUUID(TheShare.note_uuid, TheShare.owner_id); res.json({ success: true, @@ -89,7 +91,7 @@ router.get('/:uuid/info', async (req, res) => { router.post('/create', async (req, res) => { const { note_uuid, params } = req.body; - const user_id = req.cookies.user_id; + const user_id = getAuth(req).userId; try { @@ -223,7 +225,8 @@ router.post('/:uuid/delete', async (req, res) => { router.get('/for/me', async (req, res) => { - const { user_id } = req.cookies; + const user_id = getAuth(req).userId; + if (!user_id) return; try { @@ -244,7 +247,7 @@ router.get('/for/me', async (req, res) => { for (const share of share_for_me) { - const note: Note | undefined = (await notes.getNoteByUUID(share.note_uuid)).note; + const note: Note | undefined = (await notes.getNoteByUUID(share.note_uuid, user_id)).note; if (!note) continue; shared_notes.push(note); @@ -274,7 +277,8 @@ router.get('/for/me', async (req, res) => { router.get('/by/me', async (req, res) => { - const user_id = req.cookies.user_id || req.signedCookies.user_id; + const user_id = getAuth(req).userId; + if (!user_id) return; try { @@ -286,7 +290,7 @@ router.get('/by/me', async (req, res) => { for (const share of my_share) { - const __note = await notes.getNoteByUUID(share.note_uuid); + const __note = await notes.getNoteByUUID(share.note_uuid, user_id); console.log(share) if (!__note.note) continue; _notes.push(__note.note); From a224378d977f103c663679b0b37a7c42dbb15be8 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Fri, 6 Feb 2026 13:16:04 +0100 Subject: [PATCH 38/46] fix --- src/assets/ts/notes.ts | 42 ++++++++++++++++++++++++ src/mcp-server/src/tools/add_note_tag.ts | 3 +- src/mcp-server/src/tools/get_note.ts | 5 +-- src/ws.ts | 19 ++++++++--- 4 files changed, 61 insertions(+), 8 deletions(-) diff --git a/src/assets/ts/notes.ts b/src/assets/ts/notes.ts index 0005a7b..334bfa8 100644 --- a/src/assets/ts/notes.ts +++ b/src/assets/ts/notes.ts @@ -124,6 +124,48 @@ import { decrypt, encrypt } from './utils/scrypto/scrypto.js'; } + public async getNoteByUUIDNoUserID(uuid: string) { + + const res: Note[] = await this.fetch(`/user/justID/id/${uuid}`).then(res => res.notes); + + const note: Note = res[0]; + + if (note && note.uuid) + { + + if (note.content_type === "text/html/crypted" && note.content) + { + + if (note.content && note.content.includes(':')) + { + + try { + note.content = decrypt(note.content, note.user_id); + return { success: true, note }; + } + catch (e) { + console.error("Error on decrypting note : ", note.uuid); + return { success: false, error: true, message: "Error on decrypting note" }; + } + + } + + } + else + { + return { success: true, note }; + } + + } + else + { + return { error: true, message: "Note introuvable" }; + } + + return { error: true, message: "Note introuvable" }; + + } + public async getPinnedNotesByUserID (user_id: string) { diff --git a/src/mcp-server/src/tools/add_note_tag.ts b/src/mcp-server/src/tools/add_note_tag.ts index b9d6819..bb3c9a5 100644 --- a/src/mcp-server/src/tools/add_note_tag.ts +++ b/src/mcp-server/src/tools/add_note_tag.ts @@ -11,11 +11,12 @@ const add_note_tag: Tool = { params: { uuid: z.string().describe('note uuid'), tagId: z.string().describe('tag id'), + userId: z.string().describe('note owner id') }, handler: async (parms) => { - const note = (await notes.getNoteByUUID(parms.uuid)).note; + const note = (await notes.getNoteByUUID(parms.uuid, parms.userId)).note; if (!note) return { content: [ diff --git a/src/mcp-server/src/tools/get_note.ts b/src/mcp-server/src/tools/get_note.ts index b48a4e1..0040947 100644 --- a/src/mcp-server/src/tools/get_note.ts +++ b/src/mcp-server/src/tools/get_note.ts @@ -9,12 +9,13 @@ const get_note: Tool = { description: "Get note by UUID", params: { - uuid: z.string().describe('note uuid') + uuid: z.string().describe('note uuid'), + userId: z.string().describe('note owner id') }, handler: async (parms) => { - const note = (await notes.getNoteByUUID(parms.uuid)).note; + const note = (await notes.getNoteByUUID(parms.uuid, parms.userId)).note; return { content: [ diff --git a/src/ws.ts b/src/ws.ts index c10b284..875884b 100644 --- a/src/ws.ts +++ b/src/ws.ts @@ -8,6 +8,8 @@ import __dirname from "./assets/ts/_dirname.js"; const config = JSON.parse(fs.readFileSync(path.join(__dirname, '../../config.json'), 'utf-8')) import notes from "./assets/ts/notes.js"; import { Note } from "./assets/ts/types.js"; +import type { Share as ShareType } from "./assets/ts/db/share/ShareTypes.js"; +import Share from "./assets/ts/db/share/Share.js"; const httpServer = createServer(); @@ -18,8 +20,9 @@ const save_note = async (note: Note): Promise => { }); } + const get_note = async (uuid: string): Promise => { - const res = await notes.getNoteByUUID(uuid); + const res = await notes.getNoteByUUIDNoUserID(uuid); if (res.note) return res.note; } @@ -45,7 +48,7 @@ io.on("connection", (socket) => { // Stocker la room du socket pour l'utiliser dans les autres événements let currentRoom: string | null = null; - socket.on("join-room", async ({ room, userId }: { room: string, userId?: string }) => { + socket.on("join-room", async ({ room, userId }: { room: string, userId: string }) => { if (!room) return; @@ -53,10 +56,12 @@ io.on("connection", (socket) => { socket.join(room); let docData = docs.get(room); + const share = await Share.get(room); + + if (!docData) + { - if (!docData) { const ydoc = new Y.Doc(); - const fragment = ydoc.getXmlFragment("prosemirror"); const awareness = new awarenessProtocol.Awareness(ydoc); const note = await get_note(room); @@ -69,6 +74,7 @@ io.on("connection", (socket) => { docs.set(room, { ydoc, awareness, saveInterval, title, icon }); docData = { ydoc, awareness, saveInterval, title, icon }; + } const { ydoc, awareness } = docData; @@ -80,9 +86,12 @@ io.on("connection", (socket) => { socket.emit("title-update", docData.title); socket.emit("icon-update", docData.icon); - if (userId) { + if (userId) + { + if (share && userId == share.owner_id) return; socket.emit('new_user', userId); } + }); socket.on("y-update", async (update: Uint8Array | number[]) => { From f78621e8a81435d3bd238079ba0017e2a00dabc3 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Fri, 6 Feb 2026 13:36:20 +0100 Subject: [PATCH 39/46] Update ws.ts --- src/ws.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ws.ts b/src/ws.ts index 875884b..d4fc6d1 100644 --- a/src/ws.ts +++ b/src/ws.ts @@ -8,7 +8,6 @@ import __dirname from "./assets/ts/_dirname.js"; const config = JSON.parse(fs.readFileSync(path.join(__dirname, '../../config.json'), 'utf-8')) import notes from "./assets/ts/notes.js"; import { Note } from "./assets/ts/types.js"; -import type { Share as ShareType } from "./assets/ts/db/share/ShareTypes.js"; import Share from "./assets/ts/db/share/Share.js"; const httpServer = createServer(); From c1f5c77364c7febb102c1a39543ef460cf124a99 Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Sat, 7 Feb 2026 18:45:18 +0100 Subject: [PATCH 40/46] pass to db v2 --- package-lock.json | 4 ++-- src/assets/ts/notes.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f9eb6eb..15eb45b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "silvernote_back", - "version": "0.3.4-beta", + "version": "1.1.11-beta", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "silvernote_back", - "version": "0.3.4-beta", + "version": "1.1.11-beta", "license": "ISC", "dependencies": { "@clerk/clerk-sdk-node": "^4.13.23", diff --git a/src/assets/ts/notes.ts b/src/assets/ts/notes.ts index 334bfa8..e54fea9 100644 --- a/src/assets/ts/notes.ts +++ b/src/assets/ts/notes.ts @@ -33,7 +33,7 @@ import { decrypt, encrypt } from './utils/scrypto/scrypto.js'; try { - const res = await nodeFetch('https://db.silvernote.fr/notes' + path, { + const res = await nodeFetch('https://db.silvernote.fr/v2/notes' + path, { method: opt.method || 'GET', body: opt.body, agent: dbAgent, From 26eca06980040ea4914b65a57ad3c0bd8ef394da Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Sun, 8 Feb 2026 22:08:12 +0100 Subject: [PATCH 41/46] Update notes.ts --- src/assets/ts/notes.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assets/ts/notes.ts b/src/assets/ts/notes.ts index e54fea9..81ad949 100644 --- a/src/assets/ts/notes.ts +++ b/src/assets/ts/notes.ts @@ -238,8 +238,8 @@ import { decrypt, encrypt } from './utils/scrypto/scrypto.js'; { try { - note.content = decrypt(note.content, note.user_id); - decryptedNotes.push(note); + const decryptedContent = decrypt(note.content, note.user_id); + decryptedNotes.push({ ...note, content: decryptedContent }); } catch (e) { console.error("Error on decrypting note : ", note.uuid); } From 0e53fb57d1663c047977a07bcd56a400474c00bc Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Tue, 10 Feb 2026 09:35:13 +0100 Subject: [PATCH 42/46] Update notes.ts --- src/assets/ts/notes.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assets/ts/notes.ts b/src/assets/ts/notes.ts index 81ad949..e3fcd9d 100644 --- a/src/assets/ts/notes.ts +++ b/src/assets/ts/notes.ts @@ -275,11 +275,11 @@ import { decrypt, encrypt } from './utils/scrypto/scrypto.js'; }); if (res.error) { - return { error: true, message: "erreur", res }; + return { error: true, message: "erreur", ...res }; } if (res.uuid) { - return { success: true, note: note }; + return { success: true, ...res }; } return { error: true, message: "réponse inattendue", res }; From 066fa1971d3b35e3bc547cf006d35537f25c429f Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Tue, 10 Feb 2026 11:16:11 +0100 Subject: [PATCH 43/46] Update jeremy_ai.json --- src/assets/config/jeremy_ai.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/config/jeremy_ai.json b/src/assets/config/jeremy_ai.json index a668f3d..3df7378 100644 --- a/src/assets/config/jeremy_ai.json +++ b/src/assets/config/jeremy_ai.json @@ -1,3 +1,3 @@ { - "prompt_system": "Tu es le chatbot de l'application de prise de notes Silvernote. Par défaut, tu parles français. Tu aides l'utilisateur à organiser ses notes, gérer ses dossiers et tags, répondre aux questions sur l'application et donner des conseils pour mieux gérer ses notes. Tes réponses doivent être toujours polies, claires, encourageantes, brèves, précises et simple, ne dit pas comment tu fait une action juste tu dis que tu la fait. Ne jamais inventer d'informations sur l'utilisateur en dehors de ce qu'il fournit. Si une question est hors sujet ou inconnue, le dire poliment. Ne pas ajouter d'informations inutiles. Toujours répondre en Markdown HTML. Les icônes des notes doivent être mises dans le champ icon: \"URL\" en utilisant un lien vers un PNG fourni par l'API https://emojiapi.dev/api/v1. Pour générer correctement l'URL, utilise le format https://emojiapi.dev/api/v1/{code_unicode}/{taille}.png, où {code_unicode} est le code unicode de l'emoji et {taille} est la taille en pixels (32 à 512). Par exemple, pour l'emoji 🐱 (code unicode 1f431) en taille 128px, l'URL sera https://emojiapi.dev/api/v1/1f431/128.png. Les todolist doivent utiliser ce format exact :
  • dsq

. Pour le Markdown, les fonctions comme **text** ou __text__ doivent être collées au texte. Tu est connecté au MCP de silvernote qui te permet d'affectuer des actions sur les notes et les tags de l'utilisateur et de les récupérer. L'utilisateur sait qui tu es sauf s'il te le demande." + "prompt_system": "Tu es le chatbot de l'application de prise de notes Silvernote. Par défaut, tu parles français. Tu aides l'utilisateur à organiser ses notes, gérer ses dossiers et tags, répondre aux questions sur l'application et donner des conseils pour mieux gérer ses notes. Tes réponses doivent être toujours polies, claires, encourageantes, brèves, précises et simple, ne dit pas comment tu fait une action juste tu dis que tu la fait. Ne jamais inventer d'informations sur l'utilisateur en dehors de ce qu'il fournit. Toujours répondre en Markdown HTML. Les icônes des notes doivent être mises dans le champ icon: \"URL\" en utilisant un lien vers un PNG fourni par l'API https://emojiapi.dev/api/v1. Pour générer correctement l'URL, utilise le format https://emojiapi.dev/api/v1/{code_unicode}/{taille}.png, où {code_unicode} est le code unicode de l'emoji et {taille} est la taille en pixels (32 à 512). Par exemple, pour l'emoji 🐱 (code unicode 1f431) en taille 128px, l'URL sera https://emojiapi.dev/api/v1/1f431/128.png. Pour le Markdown, les fonctions comme **text** ou __text__ doivent être collées au texte. Tu est connecté au MCP de silvernote qui te permet d'affectuer des actions sur les notes et les tags de l'utilisateur et de les récupérer. Tu ne doit en aucun cas donné des information d'un autre utilisateur. L'utilisateur sait qui tu es sauf s'il te le demande." } From 71c5e8a07800d796ae49983a534d9c86853e855d Mon Sep 17 00:00:00 2001 From: mister_papaye Date: Tue, 10 Feb 2026 12:01:59 +0100 Subject: [PATCH 44/46] add build with swc compiler --- .swcrc | 21 + package-lock.json | 2055 +++++++++++++++++++++++- package.json | 14 +- src/assets/ts/utils/scrypto/scrypto.ts | 21 +- 4 files changed, 2021 insertions(+), 90 deletions(-) create mode 100644 .swcrc diff --git a/.swcrc b/.swcrc new file mode 100644 index 0000000..fa9525c --- /dev/null +++ b/.swcrc @@ -0,0 +1,21 @@ +{ + "jsc": { + "parser": { + "syntax": "typescript", + "tsx": false, + "decorators": true + }, + "target": "es2022", + "loose": false, + "externalHelpers": true, + "minify": { + "compress": true, + "mangle": true + } + }, + "module": { + "type": "es6" + }, + "minify": true, + "sourceMaps": true +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 15eb45b..7b5f0a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,13 +38,14 @@ "socket.io": "^4.8.1", "socket.io-client": "^4.8.1", "stripe": "^18.3.0", - "typescript": "^5.8.3", "xmldom": "^0.6.0", "y-prosemirror": "^1.3.7", "y-protocols": "^1.0.6", "yjs": "^13.6.27" }, "devDependencies": { + "@swc/cli": "^0.8.0", + "@swc/core": "^1.15.11", "@types/cookie-parser": "^1.4.9", "@types/cors": "^2.8.19", "@types/jsdom": "^21.1.7", @@ -56,7 +57,8 @@ "@types/node-fetch": "^2.6.13", "@types/xmldom": "^0.1.34", "esbuild": "^0.25.12", - "multer": "^2.0.2" + "multer": "^2.0.2", + "typescript": "^5.9.3" } }, "node_modules/@asamuzakjp/css-color": { @@ -109,6 +111,17 @@ "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", "license": "MIT" }, + "node_modules/@borewit/text-codec": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.1.tgz", + "integrity": "sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/@clerk/backend": { "version": "2.6.0", "license": "MIT", @@ -1076,6 +1089,329 @@ "node": ">=18" } }, + "node_modules/@napi-rs/nice": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.1.1.tgz", + "integrity": "sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/nice-android-arm-eabi": "1.1.1", + "@napi-rs/nice-android-arm64": "1.1.1", + "@napi-rs/nice-darwin-arm64": "1.1.1", + "@napi-rs/nice-darwin-x64": "1.1.1", + "@napi-rs/nice-freebsd-x64": "1.1.1", + "@napi-rs/nice-linux-arm-gnueabihf": "1.1.1", + "@napi-rs/nice-linux-arm64-gnu": "1.1.1", + "@napi-rs/nice-linux-arm64-musl": "1.1.1", + "@napi-rs/nice-linux-ppc64-gnu": "1.1.1", + "@napi-rs/nice-linux-riscv64-gnu": "1.1.1", + "@napi-rs/nice-linux-s390x-gnu": "1.1.1", + "@napi-rs/nice-linux-x64-gnu": "1.1.1", + "@napi-rs/nice-linux-x64-musl": "1.1.1", + "@napi-rs/nice-openharmony-arm64": "1.1.1", + "@napi-rs/nice-win32-arm64-msvc": "1.1.1", + "@napi-rs/nice-win32-ia32-msvc": "1.1.1", + "@napi-rs/nice-win32-x64-msvc": "1.1.1" + } + }, + "node_modules/@napi-rs/nice-android-arm-eabi": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.1.1.tgz", + "integrity": "sha512-kjirL3N6TnRPv5iuHw36wnucNqXAO46dzK9oPb0wj076R5Xm8PfUVA9nAFB5ZNMmfJQJVKACAPd/Z2KYMppthw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-android-arm64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.1.1.tgz", + "integrity": "sha512-blG0i7dXgbInN5urONoUCNf+DUEAavRffrO7fZSeoRMJc5qD+BJeNcpr54msPF6qfDD6kzs9AQJogZvT2KD5nw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-arm64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.1.1.tgz", + "integrity": "sha512-s/E7w45NaLqTGuOjC2p96pct4jRfo61xb9bU1unM/MJ/RFkKlJyJDx7OJI/O0ll/hrfpqKopuAFDV8yo0hfT7A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-x64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.1.1.tgz", + "integrity": "sha512-dGoEBnVpsdcC+oHHmW1LRK5eiyzLwdgNQq3BmZIav+9/5WTZwBYX7r5ZkQC07Nxd3KHOCkgbHSh4wPkH1N1LiQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-freebsd-x64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.1.1.tgz", + "integrity": "sha512-kHv4kEHAylMYmlNwcQcDtXjklYp4FCf0b05E+0h6nDHsZ+F0bDe04U/tXNOqrx5CmIAth4vwfkjjUmp4c4JktQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm-gnueabihf": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.1.1.tgz", + "integrity": "sha512-E1t7K0efyKXZDoZg1LzCOLxgolxV58HCkaEkEvIYQx12ht2pa8hoBo+4OB3qh7e+QiBlp1SRf+voWUZFxyhyqg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.1.1.tgz", + "integrity": "sha512-CIKLA12DTIZlmTaaKhQP88R3Xao+gyJxNWEn04wZwC2wmRapNnxCUZkVwggInMJvtVElA+D4ZzOU5sX4jV+SmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-musl": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.1.1.tgz", + "integrity": "sha512-+2Rzdb3nTIYZ0YJF43qf2twhqOCkiSrHx2Pg6DJaCPYhhaxbLcdlV8hCRMHghQ+EtZQWGNcS2xF4KxBhSGeutg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-ppc64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.1.1.tgz", + "integrity": "sha512-4FS8oc0GeHpwvv4tKciKkw3Y4jKsL7FRhaOeiPei0X9T4Jd619wHNe4xCLmN2EMgZoeGg+Q7GY7BsvwKpL22Tg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-riscv64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.1.1.tgz", + "integrity": "sha512-HU0nw9uD4FO/oGCCk409tCi5IzIZpH2agE6nN4fqpwVlCn5BOq0MS1dXGjXaG17JaAvrlpV5ZeyZwSon10XOXw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-s390x-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.1.1.tgz", + "integrity": "sha512-2YqKJWWl24EwrX0DzCQgPLKQBxYDdBxOHot1KWEq7aY2uYeX+Uvtv4I8xFVVygJDgf6/92h9N3Y43WPx8+PAgQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.1.1.tgz", + "integrity": "sha512-/gaNz3R92t+dcrfCw/96pDopcmec7oCcAQ3l/M+Zxr82KT4DljD37CpgrnXV+pJC263JkW572pdbP3hP+KjcIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-musl": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.1.1.tgz", + "integrity": "sha512-xScCGnyj/oppsNPMnevsBe3pvNaoK7FGvMjT35riz9YdhB2WtTG47ZlbxtOLpjeO9SqqQ2J2igCmz6IJOD5JYw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-openharmony-arm64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-openharmony-arm64/-/nice-openharmony-arm64-1.1.1.tgz", + "integrity": "sha512-6uJPRVwVCLDeoOaNyeiW0gp2kFIM4r7PL2MczdZQHkFi9gVlgm+Vn+V6nTWRcu856mJ2WjYJiumEajfSm7arPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-arm64-msvc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.1.1.tgz", + "integrity": "sha512-uoTb4eAvM5B2aj/z8j+Nv8OttPf2m+HVx3UjA5jcFxASvNhQriyCQF1OB1lHL43ZhW+VwZlgvjmP5qF3+59atA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-ia32-msvc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.1.1.tgz", + "integrity": "sha512-CNQqlQT9MwuCsg1Vd/oKXiuH+TcsSPJmlAFc5frFyX/KkOh0UpBLEj7aoY656d5UKZQMQFP7vJNa1DNUNORvug==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-x64-msvc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.1.1.tgz", + "integrity": "sha512-vB+4G/jBQCAh0jelMTY3+kgFy00Hlx2f2/1zjMoH821IbplbWZOkLiTYXQkygNTzQJTq5cvwBDgn2ppHD+bglQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@peculiar/asn1-schema": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.5.0.tgz", @@ -1140,6 +1476,19 @@ "integrity": "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==", "license": "MIT" }, + "node_modules/@sindresorhus/is": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", + "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, "node_modules/@socket.io/component-emitter": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", @@ -1150,17 +1499,317 @@ "version": "1.0.1", "license": "MIT" }, - "node_modules/@tiptap/core": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.5.1.tgz", - "integrity": "sha512-OmnL68v+DAHEGEO9C48oV1/F6VUOzb6ozDySrer0cxtbasVlt4QjndoXg99Db3lSgoL0JgRSHR+dBge5RbILAQ==", + "node_modules/@swc/cli": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@swc/cli/-/cli-0.8.0.tgz", + "integrity": "sha512-vzUkYzlqLe9dC+B0ZIH62CzfSZOCTjIsmquYyyyi45JCm1xmRfLDKeEeMrEPPyTWnEEN84e4iVd49Tgqa+2GaA==", + "dev": true, "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" + "dependencies": { + "@swc/counter": "^0.1.3", + "@xhmikosr/bin-wrapper": "^13.0.5", + "commander": "^8.3.0", + "minimatch": "^9.0.3", + "piscina": "^4.3.1", + "semver": "^7.3.8", + "slash": "3.0.0", + "source-map": "^0.7.3", + "tinyglobby": "^0.2.13" }, - "peerDependencies": { - "@tiptap/pm": "^3.5.1" + "bin": { + "spack": "bin/spack.js", + "swc": "bin/swc.js", + "swcx": "bin/swcx.js" + }, + "engines": { + "node": ">= 20.19.0" + }, + "peerDependencies": { + "@swc/core": "^1.2.66", + "chokidar": "^5.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@swc/cli/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@swc/cli/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@swc/core": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.11.tgz", + "integrity": "sha512-iLmLTodbYxU39HhMPaMUooPwO/zqJWvsqkrXv1ZI38rMb048p6N7qtAtTp37sw9NzSrvH6oli8EdDygo09IZ/w==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.25" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.15.11", + "@swc/core-darwin-x64": "1.15.11", + "@swc/core-linux-arm-gnueabihf": "1.15.11", + "@swc/core-linux-arm64-gnu": "1.15.11", + "@swc/core-linux-arm64-musl": "1.15.11", + "@swc/core-linux-x64-gnu": "1.15.11", + "@swc/core-linux-x64-musl": "1.15.11", + "@swc/core-win32-arm64-msvc": "1.15.11", + "@swc/core-win32-ia32-msvc": "1.15.11", + "@swc/core-win32-x64-msvc": "1.15.11" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.17" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.11.tgz", + "integrity": "sha512-QoIupRWVH8AF1TgxYyeA5nS18dtqMuxNwchjBIwJo3RdwLEFiJq6onOx9JAxHtuPwUkIVuU2Xbp+jCJ7Vzmgtg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.11.tgz", + "integrity": "sha512-S52Gu1QtPSfBYDiejlcfp9GlN+NjTZBRRNsz8PNwBgSE626/FUf2PcllVUix7jqkoMC+t0rS8t+2/aSWlMuQtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.11.tgz", + "integrity": "sha512-lXJs8oXo6Z4yCpimpQ8vPeCjkgoHu5NoMvmJZ8qxDyU99KVdg6KwU9H79vzrmB+HfH+dCZ7JGMqMF//f8Cfvdg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.11.tgz", + "integrity": "sha512-chRsz1K52/vj8Mfq/QOugVphlKPWlMh10V99qfH41hbGvwAU6xSPd681upO4bKiOr9+mRIZZW+EfJqY42ZzRyA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.11.tgz", + "integrity": "sha512-PYftgsTaGnfDK4m6/dty9ryK1FbLk+LosDJ/RJR2nkXGc8rd+WenXIlvHjWULiBVnS1RsjHHOXmTS4nDhe0v0w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.11.tgz", + "integrity": "sha512-DKtnJKIHiZdARyTKiX7zdRjiDS1KihkQWatQiCHMv+zc2sfwb4Glrodx2VLOX4rsa92NLR0Sw8WLcPEMFY1szQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.11.tgz", + "integrity": "sha512-mUjjntHj4+8WBaiDe5UwRNHuEzLjIWBTSGTw0JT9+C9/Yyuh4KQqlcEQ3ro6GkHmBGXBFpGIj/o5VMyRWfVfWw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.11.tgz", + "integrity": "sha512-ZkNNG5zL49YpaFzfl6fskNOSxtcZ5uOYmWBkY4wVAvgbSAQzLRVBp+xArGWh2oXlY/WgL99zQSGTv7RI5E6nzA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.11.tgz", + "integrity": "sha512-6XnzORkZCQzvTQ6cPrU7iaT9+i145oLwnin8JrfsLG41wl26+5cNQ2XV3zcbrnFEV6esjOceom9YO1w9mGJByw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.11.tgz", + "integrity": "sha512-IQ2n6af7XKLL6P1gIeZACskSxK8jWtoKpJWLZmdXTDj1MGzktUy4i+FvpdtxFmJWNavRWH1VmTr6kAubRDHeKw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@swc/types": { + "version": "0.1.25", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.25.tgz", + "integrity": "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/@tiptap/core": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.5.1.tgz", + "integrity": "sha512-OmnL68v+DAHEGEO9C48oV1/F6VUOzb6ozDySrer0cxtbasVlt4QjndoXg99Db3lSgoL0JgRSHR+dBge5RbILAQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/pm": "^3.5.1" } }, "node_modules/@tiptap/extension-blockquote": { @@ -1523,6 +2172,32 @@ "url": "https://github.com/sponsors/ueberdosis" } }, + "node_modules/@tokenizer/inflate": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.2.7.tgz", + "integrity": "sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "fflate": "^0.8.2", + "token-types": "^6.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/body-parser": { "version": "1.19.6", "license": "MIT", @@ -1584,6 +2259,13 @@ "@types/send": "*" } }, + "node_modules/@types/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/http-errors": { "version": "2.0.5", "license": "MIT" @@ -1689,58 +2371,228 @@ "version": "22.15.30", "license": "MIT", "dependencies": { - "undici-types": "~6.21.0" + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/node-fetch": { + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.4" + } + }, + "node_modules/@types/qs": { + "version": "6.14.0", + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "0.17.5", + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.8", + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/xmldom": { + "version": "0.1.34", + "resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.34.tgz", + "integrity": "sha512-7eZFfxI9XHYjJJuugddV6N5YNeXgQE1lArWOcd1eCOKWb/FGs5SIjacSYuEJuwhsGS3gy4RuZ5EUIcqYscuPDA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@xhmikosr/archive-type": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@xhmikosr/archive-type/-/archive-type-7.1.0.tgz", + "integrity": "sha512-xZEpnGplg1sNPyEgFh0zbHxqlw5dtYg6viplmWSxUj12+QjU9SKu3U/2G73a15pEjLaOqTefNSZ1fOPUOT4Xgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "file-type": "^20.5.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@xhmikosr/bin-check": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@xhmikosr/bin-check/-/bin-check-7.1.0.tgz", + "integrity": "sha512-y1O95J4mnl+6MpVmKfMYXec17hMEwE/yeCglFNdx+QvLLtP0yN4rSYcbkXnth+lElBuKKek2NbvOfOGPpUXCvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^5.1.1", + "isexe": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@xhmikosr/bin-wrapper": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@xhmikosr/bin-wrapper/-/bin-wrapper-13.2.0.tgz", + "integrity": "sha512-t9U9X0sDPRGDk5TGx4dv5xiOvniVJpXnfTuynVKwHgtib95NYEw4MkZdJqhoSiz820D9m0o6PCqOPMXz0N9fIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xhmikosr/bin-check": "^7.1.0", + "@xhmikosr/downloader": "^15.2.0", + "@xhmikosr/os-filter-obj": "^3.0.0", + "bin-version-check": "^5.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@xhmikosr/decompress": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@xhmikosr/decompress/-/decompress-10.2.0.tgz", + "integrity": "sha512-MmDBvu0+GmADyQWHolcZuIWffgfnuTo4xpr2I/Qw5Ox0gt+e1Be7oYqJM4te5ylL6mzlcoicnHVDvP27zft8tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xhmikosr/decompress-tar": "^8.1.0", + "@xhmikosr/decompress-tarbz2": "^8.1.0", + "@xhmikosr/decompress-targz": "^8.1.0", + "@xhmikosr/decompress-unzip": "^7.1.0", + "graceful-fs": "^4.2.11", + "strip-dirs": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@xhmikosr/decompress-tar": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@xhmikosr/decompress-tar/-/decompress-tar-8.1.0.tgz", + "integrity": "sha512-m0q8x6lwxenh1CrsTby0Jrjq4vzW/QU1OLhTHMQLEdHpmjR1lgahGz++seZI0bXF3XcZw3U3xHfqZSz+JPP2Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "file-type": "^20.5.0", + "is-stream": "^2.0.1", + "tar-stream": "^3.1.7" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@xhmikosr/decompress-tarbz2": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@xhmikosr/decompress-tarbz2/-/decompress-tarbz2-8.1.0.tgz", + "integrity": "sha512-aCLfr3A/FWZnOu5eqnJfme1Z1aumai/WRw55pCvBP+hCGnTFrcpsuiaVN5zmWTR53a8umxncY2JuYsD42QQEbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xhmikosr/decompress-tar": "^8.0.1", + "file-type": "^20.5.0", + "is-stream": "^2.0.1", + "seek-bzip": "^2.0.0", + "unbzip2-stream": "^1.4.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@xhmikosr/decompress-targz": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@xhmikosr/decompress-targz/-/decompress-targz-8.1.0.tgz", + "integrity": "sha512-fhClQ2wTmzxzdz2OhSQNo9ExefrAagw93qaG1YggoIz/QpI7atSRa7eOHv4JZkpHWs91XNn8Hry3CwUlBQhfPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xhmikosr/decompress-tar": "^8.0.1", + "file-type": "^20.5.0", + "is-stream": "^2.0.1" + }, + "engines": { + "node": ">=18" } }, - "node_modules/@types/node-fetch": { - "version": "2.6.13", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz", - "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==", + "node_modules/@xhmikosr/decompress-unzip": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@xhmikosr/decompress-unzip/-/decompress-unzip-7.1.0.tgz", + "integrity": "sha512-oqTYAcObqTlg8owulxFTqiaJkfv2SHsxxxz9Wg4krJAHVzGWlZsU8tAB30R6ow+aHrfv4Kub6WQ8u04NWVPUpA==", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*", - "form-data": "^4.0.4" + "file-type": "^20.5.0", + "get-stream": "^6.0.1", + "yauzl": "^3.1.2" + }, + "engines": { + "node": ">=18" } }, - "node_modules/@types/qs": { - "version": "6.14.0", - "license": "MIT" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "license": "MIT" - }, - "node_modules/@types/send": { - "version": "0.17.5", + "node_modules/@xhmikosr/downloader": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/@xhmikosr/downloader/-/downloader-15.2.0.tgz", + "integrity": "sha512-lAqbig3uRGTt0sHNIM4vUG9HoM+mRl8K28WuYxyXLCUT6pyzl4Y4i0LZ3jMEsCYZ6zjPZbO9XkG91OSTd4si7g==", + "dev": true, "license": "MIT", "dependencies": { - "@types/mime": "^1", - "@types/node": "*" + "@xhmikosr/archive-type": "^7.1.0", + "@xhmikosr/decompress": "^10.2.0", + "content-disposition": "^0.5.4", + "defaults": "^2.0.2", + "ext-name": "^5.0.0", + "file-type": "^20.5.0", + "filenamify": "^6.0.0", + "get-stream": "^6.0.1", + "got": "^13.0.0" + }, + "engines": { + "node": ">=18" } }, - "node_modules/@types/serve-static": { - "version": "1.15.8", + "node_modules/@xhmikosr/downloader/node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, "license": "MIT", "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" } }, - "node_modules/@types/tough-cookie": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", - "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/xmldom": { - "version": "0.1.34", - "resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.34.tgz", - "integrity": "sha512-7eZFfxI9XHYjJJuugddV6N5YNeXgQE1lArWOcd1eCOKWb/FGs5SIjacSYuEJuwhsGS3gy4RuZ5EUIcqYscuPDA==", + "node_modules/@xhmikosr/os-filter-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@xhmikosr/os-filter-obj/-/os-filter-obj-3.0.0.tgz", + "integrity": "sha512-siPY6BD5dQ2SZPl3I0OZBHL27ZqZvLEosObsZRQ1NUB8qcxegwt0T9eKtV96JMFQpIz1elhkzqOg4c/Ri6Dp9A==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "arch": "^3.0.0" + }, + "engines": { + "node": "^14.14.0 || >=16.0.0" + } }, "node_modules/accepts": { "version": "2.0.0", @@ -1804,6 +2656,8 @@ }, "node_modules/anymatch": { "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", @@ -1813,6 +2667,18 @@ "node": ">= 8" } }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/append-field": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", @@ -1820,6 +2686,27 @@ "dev": true, "license": "MIT" }, + "node_modules/arch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-3.0.0.tgz", + "integrity": "sha512-AmIAC+Wtm2AU8lGfTtHsw0Y9Qtftx2YXEEtiBP10xFUtMOA+sHHx6OAddyL52mUKh1vsXQ6/w1mVDptZCyUt4Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/argon2": { "version": "0.44.0", "resolved": "https://registry.npmjs.org/argon2/-/argon2-0.44.0.tgz", @@ -1917,6 +2804,21 @@ "version": "1.0.2", "license": "MIT" }, + "node_modules/bare-events": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", + "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", + "dev": true, + "license": "Apache-2.0", + "peerDependencies": { + "bare-abort-controller": "*" + }, + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + } + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -1987,8 +2889,45 @@ "node": "*" } }, + "node_modules/bin-version": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-6.0.0.tgz", + "integrity": "sha512-nk5wEsP4RiKjG+vF+uG8lFsEn4d7Y6FVDamzzftSunXOoOcOOkzcWdKVlGgFFwlUQCj63SgnUkLLGF8v7lufhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^5.0.0", + "find-versions": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bin-version-check": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-5.1.0.tgz", + "integrity": "sha512-bYsvMqJ8yNGILLz1KP9zKLzQ6YpljV3ln1gqhuLkUtyfGi3qXKGuK2p+U4NAvjVFzDFiBBtOpCOSFNuYYEGZ5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bin-version": "^6.0.0", + "semver": "^7.5.3", + "semver-truncate": "^3.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/binary-extensions": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "license": "MIT", "engines": { "node": ">=8" @@ -2031,6 +2970,8 @@ }, "node_modules/braces": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -2039,6 +2980,41 @@ "node": ">=8" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/buffer-equal-constant-time": { "version": "1.0.1", "license": "BSD-3-Clause" @@ -2069,6 +3045,35 @@ "node": ">= 0.8" } }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "10.2.14", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", + "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "license": "MIT", @@ -2165,25 +3170,21 @@ "license": "BSD-2-Clause" }, "node_modules/chokidar": { - "version": "3.6.0", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "readdirp": "^5.0.0" }, "engines": { - "node": ">= 8.10.0" + "node": ">= 20.19.0" }, "funding": { "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" } }, "node_modules/color-convert": { @@ -2216,6 +3217,16 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/concat-map": { "version": "0.0.1", "license": "MIT" @@ -2472,6 +3483,35 @@ "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", "license": "MIT" }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/deepmerge": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", @@ -2481,6 +3521,29 @@ "node": ">=0.10.0" } }, + "node_modules/defaults": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-2.0.2.tgz", + "integrity": "sha512-cuIw0PImdp76AOfgkjbW4VhQODRmNNcKR73vdCH5cLd/ifj7aamfoXvYgfGkEAjNJZ3ozMIy9Gu2LutUkGEPbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -2898,6 +3961,16 @@ "node": ">= 0.6" } }, + "node_modules/events-universal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", + "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.7.0" + } + }, "node_modules/eventsource": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", @@ -2919,6 +3992,37 @@ "node": ">=18.0.0" } }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, "node_modules/express": { "version": "5.1.0", "license": "MIT", @@ -2964,14 +4068,41 @@ "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz", "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==", "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/express-rate-limit" + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, + "node_modules/ext-list": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", + "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.28.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ext-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", + "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ext-list": "^2.0.0", + "sort-keys-length": "^1.0.0" }, - "peerDependencies": { - "express": ">= 4.11" + "engines": { + "node": ">=4" } }, "node_modules/extend": { @@ -2995,6 +4126,13 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -3005,6 +4143,24 @@ "version": "1.3.0", "license": "Unlicense" }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, "node_modules/fetch-blob": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", @@ -3028,8 +4184,65 @@ "node": "^12.20 || >= 14.13" } }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "dev": true, + "license": "MIT" + }, + "node_modules/file-type": { + "version": "20.5.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-20.5.0.tgz", + "integrity": "sha512-BfHZtG/l9iMm4Ecianu7P8HRD2tBHLtjXinm4X62XBOYzi7CYA7jyqfJzOvXHqzVrVPYqBo2/GvbARMaaJkKVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tokenizer/inflate": "^0.2.6", + "strtok3": "^10.2.0", + "token-types": "^6.0.0", + "uint8array-extras": "^1.4.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/filename-reserved-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-3.0.0.tgz", + "integrity": "sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/filenamify": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-6.0.0.tgz", + "integrity": "sha512-vqIlNogKeyD3yzrm0yhRMQg8hOVwYcYRfjEoODd49iCprMn4HL85gK3HcykQE53EPIpX3HcAbGA5ELQv216dAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "filename-reserved-regex": "^3.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/fill-range": { "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -3053,6 +4266,22 @@ "node": ">= 0.8" } }, + "node_modules/find-versions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-5.1.0.tgz", + "integrity": "sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver-regex": "^4.0.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/follow-redirects": { "version": "1.15.11", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", @@ -3114,6 +4343,16 @@ "node": ">= 6" } }, + "node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.17" + } + }, "node_modules/form-data/node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -3269,6 +4508,19 @@ "node": ">= 0.4" } }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -3300,6 +4552,8 @@ }, "node_modules/glob-parent": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -3404,6 +4658,39 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/got": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/got/-/got-13.0.0.tgz", + "integrity": "sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, "node_modules/gtoken": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz", @@ -3543,6 +4830,13 @@ "integrity": "sha512-LbLqfXgJMmy81t+7c14mnulFHJ170cM6E+0vMXR9k/ZiZwgX8i5pNgjTCX3SO4VeUsFLV+8InixoretwU+MjBQ==", "license": "BSD-like" }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, + "license": "BSD-2-Clause" + }, "node_modules/http-errors": { "version": "2.0.0", "license": "MIT", @@ -3585,6 +4879,33 @@ "npm": ">=1.3.7" } }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/http2-wrapper/node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/https-proxy-agent": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", @@ -3598,6 +4919,16 @@ "node": ">= 14" } }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "license": "MIT", @@ -3608,6 +4939,27 @@ "node": ">=0.10.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/ignore-by-default": { "version": "1.0.1", "license": "ISC" @@ -3616,6 +4968,16 @@ "version": "2.0.4", "license": "ISC" }, + "node_modules/inspect-with-kind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/inspect-with-kind/-/inspect-with-kind-1.0.5.tgz", + "integrity": "sha512-MAQUJuIo7Xqk8EVNP+6d3CKq9c80hi4tjIbIAT6lmGW9W6WzlHiu9PS8uSuUYU+Do+j1baiFp3H25XEVxDIG2g==", + "dev": true, + "license": "ISC", + "dependencies": { + "kind-of": "^6.0.2" + } + }, "node_modules/ipaddr.js": { "version": "1.9.1", "license": "MIT", @@ -3625,6 +4987,8 @@ }, "node_modules/is-binary-path": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" @@ -3635,6 +4999,8 @@ }, "node_modules/is-extglob": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -3651,6 +5017,8 @@ }, "node_modules/is-glob": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -3661,11 +5029,23 @@ }, "node_modules/is-number": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "license": "MIT", "engines": { "node": ">=0.12.0" } }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -3680,6 +5060,19 @@ "version": "1.0.2", "license": "MIT" }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -3797,6 +5190,13 @@ "bignumber.js": "^9.0.0" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, "node_modules/json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", @@ -3869,6 +5269,26 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/lib0": { "version": "0.2.114", "resolved": "https://registry.npmjs.org/lib0/-/lib0-0.2.114.tgz", @@ -3972,6 +5392,19 @@ "tslib": "^2.0.3" } }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lru-cache": { "version": "7.18.3", "license": "ISC", @@ -4067,6 +5500,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, "node_modules/mime-db": { "version": "1.54.0", "license": "MIT", @@ -4084,6 +5524,29 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "3.1.2", "license": "ISC", @@ -4404,18 +5867,94 @@ "engines": { "node": ">=10" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/nodemon/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/nodemon/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" } }, "node_modules/normalize-path": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/normalize-url": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.1.tgz", + "integrity": "sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/nth-check": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", @@ -4475,6 +6014,22 @@ "wrappy": "1" } }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/openai": { "version": "5.12.2", "license": "Apache-2.0", @@ -4500,6 +6055,16 @@ "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==", "license": "MIT" }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + } + }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -4563,6 +6128,13 @@ "node": ">=16" } }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -4577,15 +6149,28 @@ "peer": true }, "node_modules/picomatch": { - "version": "2.3.1", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, "license": "MIT", "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/piscina": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.9.2.tgz", + "integrity": "sha512-Fq0FERJWFEUpB4eSY59wSNwXD4RYqR+nR/WiEVcZW8IWfVBxJJafcgTEZDQo8k3w0sUarJ8RyVbbUF4GQ2LGbQ==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "@napi-rs/nice": "^1.0.1" + } + }, "node_modules/pkce-challenge": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz", @@ -4956,13 +6541,19 @@ } }, "node_modules/readdirp": { - "version": "3.6.0", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "dev": true, "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, + "optional": true, + "peer": true, "engines": { - "node": ">=8.10.0" + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, "node_modules/request": { @@ -5063,6 +6654,29 @@ "node": ">=0.10.0" } }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/rimraf": { "version": "5.0.10", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", @@ -5138,6 +6752,30 @@ "node": ">=v12.22.7" } }, + "node_modules/seek-bzip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-2.0.0.tgz", + "integrity": "sha512-SMguiTnYrhpLdk3PwfzHeotrcwi8bNV4iemL9tx9poR/yeaMYwB9VzR1w7b57DuWpuqR8n6oZboi0hj3AxZxQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^6.0.0" + }, + "bin": { + "seek-bunzip": "bin/seek-bunzip", + "seek-table": "bin/seek-bzip-table" + } + }, + "node_modules/seek-bzip/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, "node_modules/semver": { "version": "7.7.2", "license": "ISC", @@ -5148,6 +6786,35 @@ "node": ">=10" } }, + "node_modules/semver-regex": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-4.0.5.tgz", + "integrity": "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semver-truncate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-3.0.0.tgz", + "integrity": "sha512-LJWA9kSvMolR51oDE6PN3kALBNaUdkxzAGcexw8gjMA8xr5zUqK0JiR3CgARSqanYF3Z1YHvsErb1KDgh+v7Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/send": { "version": "1.2.0", "license": "MIT", @@ -5295,6 +6962,16 @@ "node": ">=10" } }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/snake-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", @@ -5505,6 +7182,42 @@ "node": ">= 0.6" } }, + "node_modules/sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-keys-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", + "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "sort-keys": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -5574,6 +7287,18 @@ "node": ">=10.0.0" } }, + "node_modules/streamx": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", + "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "events-universal": "^1.0.0", + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + } + }, "node_modules/string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", @@ -5676,6 +7401,27 @@ "node": ">=8" } }, + "node_modules/strip-dirs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-3.0.0.tgz", + "integrity": "sha512-I0sdgcFTfKQlUPZyAqPJmSG3HLO9rWDFnxonnIbskYNM3DwFOeTNB5KzVq3dA1GdRAc/25b5Y7UO2TQfKWw4aQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "inspect-with-kind": "^1.0.5", + "is-plain-obj": "^1.1.0" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/stripe": { "version": "18.3.0", "license": "MIT", @@ -5694,6 +7440,23 @@ } } }, + "node_modules/strtok3": { + "version": "10.3.4", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.4.tgz", + "integrity": "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/supports-color": { "version": "5.5.0", "license": "MIT", @@ -5721,6 +7484,82 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "license": "MIT" }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/tar-stream/node_modules/b4a": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", + "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", + "dev": true, + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } + } + }, + "node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/text-decoder/node_modules/b4a": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", + "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", + "dev": true, + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, "node_modules/tldts": { "version": "7.0.16", "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.16.tgz", @@ -5747,6 +7586,8 @@ }, "node_modules/to-regex-range": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -5780,6 +7621,25 @@ "node": ">=0.6" } }, + "node_modules/token-types": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.2.tgz", + "integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@borewit/text-codec": "^0.2.1", + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/touch": { "version": "3.1.1", "license": "ISC", @@ -5863,7 +7723,10 @@ "license": "MIT" }, "node_modules/typescript": { - "version": "5.8.3", + "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", @@ -5879,6 +7742,30 @@ "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", "license": "MIT" }, + "node_modules/uint8array-extras": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", + "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, "node_modules/undefsafe": { "version": "2.0.5", "license": "MIT" @@ -6252,6 +8139,20 @@ "yjs": "^13.0.0" } }, + "node_modules/yauzl": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.2.0.tgz", + "integrity": "sha512-Ow9nuGZE+qp1u4JIPvg+uCiUr7xGQWdff7JQSk5VGYTAZMDe2q8lxJ10ygv10qmSj031Ty/6FNJpLO4o1Sgc+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "pend": "~1.2.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/yjs": { "version": "13.6.27", "resolved": "https://registry.npmjs.org/yjs/-/yjs-13.6.27.tgz", diff --git a/package.json b/package.json index 1cbadca..904eb45 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,12 @@ "main": "index.js", "scripts": { "start": "node dist/app.js", - "dev": "npm run build && npm start", - "build": "tsc" + "dev:old": "tsc && npm start", + "build:old": "tsc", + "dev": "swc src -w -d dist", + "build": "npm run type-check-once && npm run build-only", + "type-check-once": "tsc --noEmit", + "build-only": "swc src -d dist --copy-files" }, "repository": { "type": "git", @@ -46,13 +50,14 @@ "socket.io": "^4.8.1", "socket.io-client": "^4.8.1", "stripe": "^18.3.0", - "typescript": "^5.8.3", "xmldom": "^0.6.0", "y-prosemirror": "^1.3.7", "y-protocols": "^1.0.6", "yjs": "^13.6.27" }, "devDependencies": { + "@swc/cli": "^0.8.0", + "@swc/core": "^1.15.11", "@types/cookie-parser": "^1.4.9", "@types/cors": "^2.8.19", "@types/jsdom": "^21.1.7", @@ -64,7 +69,8 @@ "@types/node-fetch": "^2.6.13", "@types/xmldom": "^0.1.34", "esbuild": "^0.25.12", - "multer": "^2.0.2" + "multer": "^2.0.2", + "typescript": "^5.9.3" }, "bugs": { "url": "https://github.com/SilverCore-Git/silvernote/issues" diff --git a/src/assets/ts/utils/scrypto/scrypto.ts b/src/assets/ts/utils/scrypto/scrypto.ts index d215a8b..1b5dcd9 100644 --- a/src/assets/ts/utils/scrypto/scrypto.ts +++ b/src/assets/ts/utils/scrypto/scrypto.ts @@ -11,17 +11,20 @@ const MASTER_KEY = Buffer.from(rawKey, 'hex'); const ALGORITHM = 'aes-256-gcm'; -function getUserKey(userId: string): Buffer { - - return crypto.hkdfSync( +function getUserKey(userId: string): Buffer +{ + + const derivedKey = crypto.hkdfSync( 'sha256', MASTER_KEY, - Buffer.alloc(0), // Salt (optionnel, vide ici) - `user-key-${userId}`, // Info : contexte unique - 32 // Longueur de clé désirée - ) as Buffer; - -} + Buffer.alloc(0), // Salt + `user-key-${userId}`, // Info + 32 // Longueur + ); + + return Buffer.from(derivedKey); + +}; function getUserFingerprint(userId: string): string { const userKey = getUserKey(userId); From 256751f5eccae0c8af37cf2d59a11d18252f6ade Mon Sep 17 00:00:00 2001 From: MisterPapaye Date: Thu, 12 Feb 2026 20:57:52 +0100 Subject: [PATCH 45/46] Update package-lock.json --- package-lock.json | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7b5f0a9..ea4ec6e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3169,24 +3169,6 @@ "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", "license": "BSD-2-Clause" }, - "node_modules/chokidar": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", - "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "readdirp": "^5.0.0" - }, - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -6540,22 +6522,6 @@ "string_decoder": "~0.10.x" } }, - "node_modules/readdirp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", - "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", From 1d80bc8d2f269b75dc9142b06c482dd269694b88 Mon Sep 17 00:00:00 2001 From: MisterPapaye Date: Thu, 12 Feb 2026 21:09:04 +0100 Subject: [PATCH 46/46] fix build --- package.json | 2 +- src/express.ts | 4 ++-- src/package.json | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 904eb45..7a21464 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "silvernote_back", - "version": "1.1.11-beta", + "version": "1.11.21-beta", "description": "", "main": "index.js", "scripts": { diff --git a/src/express.ts b/src/express.ts index d469194..b461bda 100644 --- a/src/express.ts +++ b/src/express.ts @@ -126,8 +126,8 @@ async function initializeMCP() { async function startServer() { await initializeMCP(); - httpServer.listen(config.PORT, () => { - console.log(`Serveur Express sur le port ${config.PORT}`); + httpServer.listen(process.env.PORT || config.PORT, () => { + console.log(`Serveur Express sur le port ${process.env.PORT || config.PORT}`); }); } diff --git a/src/package.json b/src/package.json index 1cbadca..00c0578 100644 --- a/src/package.json +++ b/src/package.json @@ -1,6 +1,6 @@ { "name": "silvernote_back", - "version": "1.1.11-beta", + "version": "1.11.21-beta", "description": "", "main": "index.js", "scripts": { @@ -46,7 +46,6 @@ "socket.io": "^4.8.1", "socket.io-client": "^4.8.1", "stripe": "^18.3.0", - "typescript": "^5.8.3", "xmldom": "^0.6.0", "y-prosemirror": "^1.3.7", "y-protocols": "^1.0.6",