diff --git a/package.json b/package.json index 6e2de622..c113832b 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "dependencies": { "@electron-toolkit/preload": "^3.0.0", "@electron-toolkit/utils": "^3.0.0", + "better-sqlite3": "^11.3.0", "electron-log": "^5.1.5", "electron-store": "^8.2.0", "electron-updater": "^6.1.7", diff --git a/resources/migrations/001_create_files_table.sql b/resources/migrations/001_create_files_table.sql new file mode 100644 index 00000000..e5d08fd8 --- /dev/null +++ b/resources/migrations/001_create_files_table.sql @@ -0,0 +1,9 @@ +CREATE TABLE IF NOT EXISTS files ( + id TEXT PRIMARY KEY, + name TEXT NOT NULL, + file_name TEXT NOT NULL, + path TEXT NOT NULL, + size INTEGER NOT NULL, + ext TEXT NOT NULL, + created_at TEXT NOT NULL +) diff --git a/src/main/db/DatabaseMigrator.ts b/src/main/db/DatabaseMigrator.ts new file mode 100644 index 00000000..927a7923 --- /dev/null +++ b/src/main/db/DatabaseMigrator.ts @@ -0,0 +1,95 @@ +import Database from 'better-sqlite3' +import { app } from 'electron' +import Logger from 'electron-log' +import * as fs from 'fs' +import * as path from 'path' + +interface Migration { + id: number + name: string + sql: string +} + +export class DatabaseMigrator { + private storageDir: string + private db: Database.Database + private migrationsDir: string + + constructor(migrationsDir: string) { + this.storageDir = path.join(app.getPath('userData'), 'Data') + this.migrationsDir = migrationsDir + this.initStorageDir() + this.initDatabase() + this.initMigrationsTable() + } + + private initStorageDir(): void { + if (!fs.existsSync(this.storageDir)) { + fs.mkdirSync(this.storageDir, { recursive: true }) + } + } + + private initDatabase(): void { + const dbPath = path.join(this.storageDir, 'data.db') + this.db = new Database(dbPath) + } + + private initMigrationsTable(): void { + this.db.exec(` + CREATE TABLE IF NOT EXISTS migrations ( + id INTEGER PRIMARY KEY, + name TEXT NOT NULL, + applied_at DATETIME DEFAULT CURRENT_TIMESTAMP + ) + `) + } + + private getAppliedMigrations(): number[] { + const stmt = this.db.prepare('SELECT id FROM migrations ORDER BY id') + return stmt.all().map((row: any) => row.id) + } + + private loadMigrations(): Migration[] { + const files = fs.readdirSync(this.migrationsDir).filter((file) => file.endsWith('.sql')) + return files + .map((file) => { + const [id, ...nameParts] = path.basename(file, '.sql').split('_') + return { + id: parseInt(id), + name: nameParts.join('_'), + sql: fs.readFileSync(path.join(this.migrationsDir, file), 'utf-8') + } + }) + .sort((a, b) => a.id - b.id) + } + + public async migrate(): Promise { + const appliedMigrations = this.getAppliedMigrations() + const allMigrations = this.loadMigrations() + + const pendingMigrations = allMigrations.filter((migration) => !appliedMigrations.includes(migration.id)) + + this.db.exec('BEGIN TRANSACTION') + + try { + for (const migration of pendingMigrations) { + Logger.log(`Applying migration: ${migration.id}_${migration.name}`) + this.db.exec(migration.sql) + + const insertStmt = this.db.prepare('INSERT INTO migrations (id, name) VALUES (?, ?)') + insertStmt.run(migration.id, migration.name) + } + + this.db.exec('COMMIT') + Logger.log('All migrations applied successfully') + } catch (error) { + this.db.exec('ROLLBACK') + Logger.error('Error applying migrations:', error) + throw error + } + } + + public close(): void { + this.db.close() + } +} diff --git a/src/main/file.ts b/src/main/file.ts index dc764f5c..556bdc6d 100644 --- a/src/main/file.ts +++ b/src/main/file.ts @@ -1,3 +1,4 @@ +import Database from 'better-sqlite3' import * as crypto from 'crypto' import { app, dialog, OpenDialogOptions } from 'electron' import * as fs from 'fs' @@ -7,19 +8,21 @@ import { v4 as uuidv4 } from 'uuid' interface FileMetadata { id: string name: string - fileName: string + file_name: string path: string size: number ext: string - createdAt: Date + created_at: Date } export class File { private storageDir: string + private db: Database.Database constructor() { this.storageDir = path.join(app.getPath('userData'), 'Data', 'Files') this.initStorageDir() + this.initDatabase() } private initStorageDir(): void { @@ -28,6 +31,11 @@ export class File { } } + private initDatabase(): void { + const dbPath = path.join(app.getPath('userData'), 'Data', 'data.db') + this.db = new Database(dbPath) + } + private async getFileHash(filePath: string): Promise { return new Promise((resolve, reject) => { const hash = crypto.createHash('md5') @@ -55,15 +63,8 @@ export class File { if (originalHash === storedHash) { const ext = path.extname(file) - return { - id: path.basename(file, ext), - name: path.basename(filePath), - fileName: file, - path: storedFilePath, - createdAt: storedStats.birthtime, - size: storedStats.size, - ext: ext - } + const id = path.basename(file, ext) + return this.getFile(id) } } } @@ -91,9 +92,9 @@ export class File { return { id: uuidv4(), name: path.basename(filePath), - fileName: path.basename(filePath), + file_name: path.basename(filePath), path: filePath, - createdAt: stats.birthtime, + created_at: stats.birthtime, size: stats.size, ext: ext } @@ -117,20 +118,41 @@ export class File { await fs.promises.copyFile(filePath, destPath) const stats = await fs.promises.stat(destPath) - return { + const fileMetadata: FileMetadata = { id: uuid, name, - fileName: uuid + ext, + file_name: uuid + ext, path: destPath, - createdAt: stats.birthtime, + created_at: stats.birthtime, size: stats.size, ext: ext } + + const stmt = this.db.prepare(` + INSERT INTO files (id, name, file_name, path, size, ext, created_at) + VALUES (?, ?, ?, ?, ?, ?, ?) + `) + + stmt.run( + fileMetadata.id, + fileMetadata.name, + fileMetadata.file_name, + fileMetadata.path, + fileMetadata.size, + fileMetadata.ext, + fileMetadata.created_at.toISOString() + ) + + return fileMetadata } async deleteFile(fileId: string): Promise { - const filePath = path.join(this.storageDir, fileId) - await fs.promises.unlink(filePath) + const fileMetadata = this.getFile(fileId) + if (fileMetadata) { + await fs.promises.unlink(fileMetadata.path) + const stmt = this.db.prepare('DELETE FROM files WHERE id = ?') + stmt.run(fileId) + } } async batchUploadFiles(filePaths: string[]): Promise { @@ -142,4 +164,25 @@ export class File { const deletePromises = fileIds.map((fileId) => this.deleteFile(fileId)) await Promise.all(deletePromises) } + + getFile(id: string): FileMetadata | null { + const stmt = this.db.prepare('SELECT * FROM files WHERE id = ?') + const row = stmt.get(id) as any + if (row) { + return { + ...row, + created_at: new Date(row.created_at) + } + } + return null + } + + getAllFiles(): FileMetadata[] { + const stmt = this.db.prepare('SELECT * FROM files') + const rows = stmt.all() as any[] + return rows.map((row) => ({ + ...row, + created_at: new Date(row.created_at) + })) + } } diff --git a/src/main/index.ts b/src/main/index.ts index 5544b39a..841ceb0e 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -1,15 +1,30 @@ import { electronApp, optimizer } from '@electron-toolkit/utils' import { app, BrowserWindow } from 'electron' +import Logger from 'electron-log' +import path from 'path' +import { DatabaseMigrator } from './db/DatabaseMigrator' import { registerIpc } from './ipc' +import { getResourcePath } from './utils' import { updateUserDataPath } from './utils/upgrade' import { createMainWindow } from './window' +async function migrateDatabase() { + const migrationsDir = path.join(getResourcePath(), 'migrations') + const migrator = new DatabaseMigrator(migrationsDir) + + await migrator.migrate() + migrator.close() + + Logger.log('Database migration completed successfully.') +} + // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. app.whenReady().then(async () => { await updateUserDataPath() + await migrateDatabase() // Set app user model id for windows electronApp.setAppUserModelId('com.kangfenmao.CherryStudio') diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 6b88d053..92d122a2 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -34,27 +34,18 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) { ipcMain.handle('zip:compress', (_, text: string) => compress(text)) ipcMain.handle('zip:decompress', (_, text: Buffer) => decompress(text)) - ipcMain.handle('file:select', async (_, options?: OpenDialogOptions) => { - return await fileManager.selectFile(options) - }) - - ipcMain.handle('file:upload', async (_, filePath: string) => { - return await fileManager.uploadFile(filePath) - }) - + ipcMain.handle('file:select', async (_, options?: OpenDialogOptions) => await fileManager.selectFile(options)) + ipcMain.handle('file:upload', async (_, filePath: string) => await fileManager.uploadFile(filePath)) ipcMain.handle('file:delete', async (_, fileId: string) => { await fileManager.deleteFile(fileId) return { success: true } }) - - ipcMain.handle('file:batchUpload', async (_, filePaths: string[]) => { - return await fileManager.batchUploadFiles(filePaths) - }) - + ipcMain.handle('file:batchUpload', async (_, filePaths: string[]) => await fileManager.batchUploadFiles(filePaths)) ipcMain.handle('file:batchDelete', async (_, fileIds: string[]) => { await fileManager.batchDeleteFiles(fileIds) return { success: true } }) + ipcMain.handle('file:getAll', () => fileManager.getAllFiles()) ipcMain.handle('minapp', (_, args) => { createMinappWindow({ diff --git a/src/main/utils/index.ts b/src/main/utils/index.ts new file mode 100644 index 00000000..42008fee --- /dev/null +++ b/src/main/utils/index.ts @@ -0,0 +1,7 @@ +import path from 'node:path' + +import { app } from 'electron' + +export function getResourcePath() { + return path.join(app.getAppPath(), 'resources') +} diff --git a/src/preload/index.d.ts b/src/preload/index.d.ts index c55baed5..9d28f9b4 100644 --- a/src/preload/index.d.ts +++ b/src/preload/index.d.ts @@ -27,6 +27,7 @@ declare global { fileDelete: (fileId: string) => Promise<{ success: boolean }> fileBatchUpload: (filePaths: string[]) => Promise fileBatchDelete: (fileIds: string[]) => Promise<{ success: boolean }> + fileGetAll: () => Promise } } } diff --git a/src/preload/index.ts b/src/preload/index.ts index 32b5f392..d0866f3e 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -20,7 +20,8 @@ const api = { fileUpload: (filePath: string) => ipcRenderer.invoke('file:upload', filePath), fileDelete: (fileId: string) => ipcRenderer.invoke('file:delete', fileId), fileBatchUpload: (filePaths: string[]) => ipcRenderer.invoke('file:batchUpload', filePaths), - fileBatchDelete: (fileIds: string[]) => ipcRenderer.invoke('file:batchDelete', fileIds) + fileBatchDelete: (fileIds: string[]) => ipcRenderer.invoke('file:batchDelete', fileIds), + fileGetAll: () => ipcRenderer.invoke('file:getAll') } // Use `contextBridge` APIs to expose Electron APIs to diff --git a/src/renderer/index.html b/src/renderer/index.html index 70acb6c0..f21888d3 100644 --- a/src/renderer/index.html +++ b/src/renderer/index.html @@ -5,7 +5,7 @@ + content="default-src 'self'; connect-src *; script-src 'self' *; worker-src 'self' blob:; style-src 'self' 'unsafe-inline' *; font-src 'self' data: *; img-src 'self' data: file: *; frame-src * file:" />
diff --git a/src/renderer/src/pages/files/FilesPage.tsx b/src/renderer/src/pages/files/FilesPage.tsx index 012ee288..05e63899 100644 --- a/src/renderer/src/pages/files/FilesPage.tsx +++ b/src/renderer/src/pages/files/FilesPage.tsx @@ -1,21 +1,60 @@ import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar' -import { Button } from 'antd' -import { FC } from 'react' +import { VStack } from '@renderer/components/Layout' +import { FileMetadata } from '@renderer/types' +import { Image, Table } from 'antd' +import { FC, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' const FilesPage: FC = () => { const { t } = useTranslation() + const [files, setFiles] = useState([]) - const handleSelectFile = async () => { - const files = await window.api.fileSelect({ - properties: ['openFile', 'multiSelections'] - }) - for (const file of files || []) { - const result = await window.api.fileUpload(file.path) - console.log('Selected file:', file, result) + useEffect(() => { + window.api.fileGetAll().then(setFiles) + }, []) + + const dataSource = files.map((file) => ({ + file: , + name: {file.name}, + size: `${(file.size / 1024 / 1024).toFixed(2)} MB`, + created_at: file.created_at.toISOString().split('T')[0] + })) + + const columns = [ + { + title: 'File', + dataIndex: 'file', + key: 'file' + }, + { + title: 'Name', + dataIndex: 'name', + key: 'name' + }, + { + title: 'Size', + dataIndex: 'size', + key: 'size', + width: '100px' + }, + { + title: 'Created At', + dataIndex: 'created_at', + key: 'created_at', + width: '120px' } - } + ] + + // const handleSelectFile = async () => { + // const files = await window.api.fileSelect({ + // properties: ['openFile', 'multiSelections'] + // }) + // for (const file of files || []) { + // const result = await window.api.fileUpload(file.path) + // console.log('Selected file:', file, result) + // } + // } return ( @@ -23,7 +62,9 @@ const FilesPage: FC = () => { {t('files.title')} - + + + ) diff --git a/src/renderer/src/types/index.ts b/src/renderer/src/types/index.ts index 4dec9f35..715c1b61 100644 --- a/src/renderer/src/types/index.ts +++ b/src/renderer/src/types/index.ts @@ -86,3 +86,13 @@ export type MinAppType = { logo: string url: string } + +export interface FileMetadata { + id: string + name: string + file_name: string + path: string + size: number + ext: string + created_at: Date +} diff --git a/yarn.lock b/yarn.lock index bb10334e..1439d7c4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1922,6 +1922,7 @@ __metadata: "@vitejs/plugin-react": "npm:^4.2.1" antd: "npm:^5.18.3" axios: "npm:^1.7.3" + better-sqlite3: "npm:^11.3.0" browser-image-compression: "npm:^2.0.2" dayjs: "npm:^1.11.11" dotenv-cli: "npm:^7.4.2" @@ -2462,6 +2463,17 @@ __metadata: languageName: node linkType: hard +"better-sqlite3@npm:^11.3.0": + version: 11.3.0 + resolution: "better-sqlite3@npm:11.3.0" + dependencies: + bindings: "npm:^1.5.0" + node-gyp: "npm:latest" + prebuild-install: "npm:^7.1.1" + checksum: 10c0/9adc99683300699581da5d7288e4a261b7d4381fd99c762fc6a0e9b1e1e226009c1333b46b10c1c453c356b20cb8be037a4616b1e717b3d1a00bd8493bec506e + languageName: node + linkType: hard + "binary-extensions@npm:^2.0.0": version: 2.3.0 resolution: "binary-extensions@npm:2.3.0" @@ -2469,6 +2481,26 @@ __metadata: languageName: node linkType: hard +"bindings@npm:^1.5.0": + version: 1.5.0 + resolution: "bindings@npm:1.5.0" + dependencies: + file-uri-to-path: "npm:1.0.0" + checksum: 10c0/3dab2491b4bb24124252a91e656803eac24292473e56554e35bbfe3cc1875332cfa77600c3bac7564049dc95075bf6fcc63a4609920ff2d64d0fe405fcf0d4ba + languageName: node + linkType: hard + +"bl@npm:^4.0.3": + version: 4.1.0 + resolution: "bl@npm:4.1.0" + dependencies: + buffer: "npm:^5.5.0" + inherits: "npm:^2.0.4" + readable-stream: "npm:^3.4.0" + checksum: 10c0/02847e1d2cb089c9dc6958add42e3cdeaf07d13f575973963335ac0fdece563a50ac770ac4c8fa06492d2dd276f6cc3b7f08c7cd9c7a7ad0f8d388b2a28def5f + languageName: node + linkType: hard + "bluebird-lst@npm:^1.0.9": version: 1.0.9 resolution: "bluebird-lst@npm:1.0.9" @@ -2564,7 +2596,7 @@ __metadata: languageName: node linkType: hard -"buffer@npm:^5.1.0": +"buffer@npm:^5.1.0, buffer@npm:^5.5.0": version: 5.7.1 resolution: "buffer@npm:5.7.1" dependencies: @@ -2797,6 +2829,13 @@ __metadata: languageName: node linkType: hard +"chownr@npm:^1.1.1": + version: 1.1.4 + resolution: "chownr@npm:1.1.4" + checksum: 10c0/ed57952a84cc0c802af900cf7136de643d3aba2eecb59d29344bc2f3f9bf703a301b9d84cdc71f82c3ffc9ccde831b0d92f5b45f91727d6c9da62f23aef9d9db + languageName: node + linkType: hard + "chownr@npm:^2.0.0": version: 2.0.0 resolution: "chownr@npm:2.0.0" @@ -3155,6 +3194,13 @@ __metadata: languageName: node linkType: hard +"deep-extend@npm:^0.6.0": + version: 0.6.0 + resolution: "deep-extend@npm:0.6.0" + checksum: 10c0/1c6b0abcdb901e13a44c7d699116d3d4279fdb261983122a3783e7273844d5f2537dc2e1c454a23fcf645917f93fbf8d07101c1d03c015a87faa662755212566 + languageName: node + linkType: hard + "deep-is@npm:^0.1.3": version: 0.1.4 resolution: "deep-is@npm:0.1.4" @@ -3205,6 +3251,13 @@ __metadata: languageName: node linkType: hard +"detect-libc@npm:^2.0.0": + version: 2.0.3 + resolution: "detect-libc@npm:2.0.3" + checksum: 10c0/88095bda8f90220c95f162bf92cad70bd0e424913e655c20578600e35b91edc261af27531cf160a331e185c0ced93944bc7e09939143225f56312d7fd800fdb7 + languageName: node + linkType: hard + "detect-node@npm:^2.0.4": version: 2.1.0 resolution: "detect-node@npm:2.1.0" @@ -3522,7 +3575,7 @@ __metadata: languageName: node linkType: hard -"end-of-stream@npm:^1.1.0": +"end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1": version: 1.4.4 resolution: "end-of-stream@npm:1.4.4" dependencies: @@ -4100,6 +4153,13 @@ __metadata: languageName: node linkType: hard +"expand-template@npm:^2.0.3": + version: 2.0.3 + resolution: "expand-template@npm:2.0.3" + checksum: 10c0/1c9e7afe9acadf9d373301d27f6a47b34e89b3391b1ef38b7471d381812537ef2457e620ae7f819d2642ce9c43b189b3583813ec395e2938319abe356a9b2f51 + languageName: node + linkType: hard + "exponential-backoff@npm:^3.1.1": version: 3.1.1 resolution: "exponential-backoff@npm:3.1.1" @@ -4222,6 +4282,13 @@ __metadata: languageName: node linkType: hard +"file-uri-to-path@npm:1.0.0": + version: 1.0.0 + resolution: "file-uri-to-path@npm:1.0.0" + checksum: 10c0/3b545e3a341d322d368e880e1c204ef55f1d45cdea65f7efc6c6ce9e0c4d22d802d5629320eb779d006fe59624ac17b0e848d83cc5af7cd101f206cb704f5519 + languageName: node + linkType: hard + "filelist@npm:^1.0.4": version: 1.0.4 resolution: "filelist@npm:1.0.4" @@ -4341,6 +4408,13 @@ __metadata: languageName: node linkType: hard +"fs-constants@npm:^1.0.0": + version: 1.0.0 + resolution: "fs-constants@npm:1.0.0" + checksum: 10c0/a0cde99085f0872f4d244e83e03a46aa387b74f5a5af750896c6b05e9077fac00e9932fdf5aef84f2f16634cd473c63037d7a512576da7d5c2b9163d1909f3a8 + languageName: node + linkType: hard + "fs-extra@npm:^10.0.0, fs-extra@npm:^10.1.0": version: 10.1.0 resolution: "fs-extra@npm:10.1.0" @@ -4492,6 +4566,13 @@ __metadata: languageName: node linkType: hard +"github-from-package@npm:0.0.0": + version: 0.0.0 + resolution: "github-from-package@npm:0.0.0" + checksum: 10c0/737ee3f52d0a27e26332cde85b533c21fcdc0b09fb716c3f8e522cfaa9c600d4a631dec9fcde179ec9d47cca89017b7848ed4d6ae6b6b78f936c06825b1fcc12 + languageName: node + linkType: hard + "glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2": version: 5.1.2 resolution: "glob-parent@npm:5.1.2" @@ -5077,13 +5158,20 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2": +"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 languageName: node linkType: hard +"ini@npm:~1.3.0": + version: 1.3.8 + resolution: "ini@npm:1.3.8" + checksum: 10c0/ec93838d2328b619532e4f1ff05df7909760b6f66d9c9e2ded11e5c1897d6f2f9980c54dd638f88654b00919ce31e827040631eab0a3969e4d1abefa0719516a + languageName: node + linkType: hard + "inline-style-parser@npm:0.2.3": version: 0.2.3 resolution: "inline-style-parser@npm:0.2.3" @@ -6577,7 +6665,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.2.6": +"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.6": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6 @@ -6675,6 +6763,13 @@ __metadata: languageName: node linkType: hard +"mkdirp-classic@npm:^0.5.2, mkdirp-classic@npm:^0.5.3": + version: 0.5.3 + resolution: "mkdirp-classic@npm:0.5.3" + checksum: 10c0/95371d831d196960ddc3833cc6907e6b8f67ac5501a6582f47dfae5eb0f092e9f8ce88e0d83afcae95d6e2b61a01741ba03714eeafb6f7a6e9dcc158ac85b168 + languageName: node + linkType: hard + "mkdirp@npm:^0.5.1": version: 0.5.6 resolution: "mkdirp@npm:0.5.6" @@ -6718,6 +6813,13 @@ __metadata: languageName: node linkType: hard +"napi-build-utils@npm:^1.0.1": + version: 1.0.2 + resolution: "napi-build-utils@npm:1.0.2" + checksum: 10c0/37fd2cd0ff2ad20073ce78d83fd718a740d568b225924e753ae51cb69d68f330c80544d487e5e5bd18e28702ed2ca469c2424ad948becd1862c1b0209542b2e9 + languageName: node + linkType: hard + "natural-compare@npm:^1.4.0": version: 1.4.0 resolution: "natural-compare@npm:1.4.0" @@ -6732,6 +6834,15 @@ __metadata: languageName: node linkType: hard +"node-abi@npm:^3.3.0": + version: 3.67.0 + resolution: "node-abi@npm:3.67.0" + dependencies: + semver: "npm:^7.3.5" + checksum: 10c0/72ce2edbdfb84745bc201a4e48aa7146fd88a0d2c80046b6b17f28439c9a7683eab846f40f1e819349c31f7d9331ed5c50d1e741208d938dd5f38b29cab2275e + languageName: node + linkType: hard + "node-addon-api@npm:^1.6.3": version: 1.7.2 resolution: "node-addon-api@npm:1.7.2" @@ -7190,6 +7301,28 @@ __metadata: languageName: node linkType: hard +"prebuild-install@npm:^7.1.1": + version: 7.1.2 + resolution: "prebuild-install@npm:7.1.2" + dependencies: + detect-libc: "npm:^2.0.0" + expand-template: "npm:^2.0.3" + github-from-package: "npm:0.0.0" + minimist: "npm:^1.2.3" + mkdirp-classic: "npm:^0.5.3" + napi-build-utils: "npm:^1.0.1" + node-abi: "npm:^3.3.0" + pump: "npm:^3.0.0" + rc: "npm:^1.2.7" + simple-get: "npm:^4.0.0" + tar-fs: "npm:^2.0.0" + tunnel-agent: "npm:^0.6.0" + bin: + prebuild-install: bin.js + checksum: 10c0/e64868ba9ef2068fd7264f5b03e5298a901e02a450acdb1f56258d88c09dea601eefdb3d1dfdff8513fdd230a92961712be0676192626a3b4d01ba154d48bdd3 + languageName: node + linkType: hard + "prelude-ls@npm:^1.2.1": version: 1.2.1 resolution: "prelude-ls@npm:1.2.1" @@ -7868,6 +8001,20 @@ __metadata: languageName: node linkType: hard +"rc@npm:^1.2.7": + version: 1.2.8 + resolution: "rc@npm:1.2.8" + dependencies: + deep-extend: "npm:^0.6.0" + ini: "npm:~1.3.0" + minimist: "npm:^1.2.0" + strip-json-comments: "npm:~2.0.1" + bin: + rc: ./cli.js + checksum: 10c0/24a07653150f0d9ac7168e52943cc3cb4b7a22c0e43c7dff3219977c2fdca5a2760a304a029c20811a0e79d351f57d46c9bde216193a0f73978496afc2b85b15 + languageName: node + linkType: hard + "react-dom@npm:^18.2.0": version: 18.3.1 resolution: "react-dom@npm:18.3.1" @@ -8063,6 +8210,17 @@ __metadata: languageName: node linkType: hard +"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0": + version: 3.6.2 + resolution: "readable-stream@npm:3.6.2" + dependencies: + inherits: "npm:^2.0.3" + string_decoder: "npm:^1.1.1" + util-deprecate: "npm:^1.0.1" + checksum: 10c0/e37be5c79c376fdd088a45fa31ea2e423e5d48854be7a22a58869b4e84d25047b193f6acb54f1012331e1bcd667ffb569c01b99d36b0bd59658fb33f513511b7 + languageName: node + linkType: hard + "readdirp@npm:~3.6.0": version: 3.6.0 resolution: "readdirp@npm:3.6.0" @@ -8428,6 +8586,13 @@ __metadata: languageName: node linkType: hard +"safe-buffer@npm:^5.0.1, safe-buffer@npm:~5.2.0": + version: 5.2.1 + resolution: "safe-buffer@npm:5.2.1" + checksum: 10c0/6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3 + languageName: node + linkType: hard + "safe-regex-test@npm:^1.0.3": version: 1.0.3 resolution: "safe-regex-test@npm:1.0.3" @@ -8595,6 +8760,24 @@ __metadata: languageName: node linkType: hard +"simple-concat@npm:^1.0.0": + version: 1.0.1 + resolution: "simple-concat@npm:1.0.1" + checksum: 10c0/62f7508e674414008910b5397c1811941d457dfa0db4fd5aa7fa0409eb02c3609608dfcd7508cace75b3a0bf67a2a77990711e32cd213d2c76f4fd12ee86d776 + languageName: node + linkType: hard + +"simple-get@npm:^4.0.0": + version: 4.0.1 + resolution: "simple-get@npm:4.0.1" + dependencies: + decompress-response: "npm:^6.0.0" + once: "npm:^1.3.1" + simple-concat: "npm:^1.0.0" + checksum: 10c0/b0649a581dbca741babb960423248899203165769747142033479a7dc5e77d7b0fced0253c731cd57cf21e31e4d77c9157c3069f4448d558ebc96cf9e1eebcf0 + languageName: node + linkType: hard + "simple-update-notifier@npm:2.0.0": version: 2.0.0 resolution: "simple-update-notifier@npm:2.0.0" @@ -8794,6 +8977,15 @@ __metadata: languageName: node linkType: hard +"string_decoder@npm:^1.1.1": + version: 1.3.0 + resolution: "string_decoder@npm:1.3.0" + dependencies: + safe-buffer: "npm:~5.2.0" + checksum: 10c0/810614ddb030e271cd591935dcd5956b2410dd079d64ff92a1844d6b7588bf992b3e1b69b0f4d34a3e06e0bd73046ac646b5264c1987b20d0601f81ef35d731d + languageName: node + linkType: hard + "stringify-entities@npm:^4.0.0": version: 4.0.4 resolution: "stringify-entities@npm:4.0.4" @@ -8829,6 +9021,13 @@ __metadata: languageName: node linkType: hard +"strip-json-comments@npm:~2.0.1": + version: 2.0.1 + resolution: "strip-json-comments@npm:2.0.1" + checksum: 10c0/b509231cbdee45064ff4f9fd73609e2bcc4e84a4d508e9dd0f31f70356473fde18abfb5838c17d56fb236f5a06b102ef115438de0600b749e818a35fbbc48c43 + languageName: node + linkType: hard + "style-to-object@npm:^1.0.0": version: 1.0.6 resolution: "style-to-object@npm:1.0.6" @@ -8909,6 +9108,31 @@ __metadata: languageName: node linkType: hard +"tar-fs@npm:^2.0.0": + version: 2.1.1 + resolution: "tar-fs@npm:2.1.1" + dependencies: + chownr: "npm:^1.1.1" + mkdirp-classic: "npm:^0.5.2" + pump: "npm:^3.0.0" + tar-stream: "npm:^2.1.4" + checksum: 10c0/871d26a934bfb7beeae4c4d8a09689f530b565f79bd0cf489823ff0efa3705da01278160da10bb006d1a793fa0425cf316cec029b32a9159eacbeaff4965fb6d + languageName: node + linkType: hard + +"tar-stream@npm:^2.1.4": + version: 2.2.0 + resolution: "tar-stream@npm:2.2.0" + dependencies: + bl: "npm:^4.0.3" + end-of-stream: "npm:^1.4.1" + fs-constants: "npm:^1.0.0" + inherits: "npm:^2.0.3" + readable-stream: "npm:^3.1.1" + checksum: 10c0/2f4c910b3ee7196502e1ff015a7ba321ec6ea837667220d7bcb8d0852d51cb04b87f7ae471008a6fb8f5b1a1b5078f62f3a82d30c706f20ada1238ac797e7692 + languageName: node + linkType: hard + "tar@npm:^6.1.11, tar@npm:^6.1.12, tar@npm:^6.2.1": version: 6.2.1 resolution: "tar@npm:6.2.1" @@ -9046,6 +9270,15 @@ __metadata: languageName: node linkType: hard +"tunnel-agent@npm:^0.6.0": + version: 0.6.0 + resolution: "tunnel-agent@npm:0.6.0" + dependencies: + safe-buffer: "npm:^5.0.1" + checksum: 10c0/4c7a1b813e7beae66fdbf567a65ec6d46313643753d0beefb3c7973d66fcec3a1e7f39759f0a0b4465883499c6dc8b0750ab8b287399af2e583823e40410a17a + languageName: node + linkType: hard + "type-check@npm:^0.4.0, type-check@npm:~0.4.0": version: 0.4.0 resolution: "type-check@npm:0.4.0" @@ -9330,6 +9563,13 @@ __metadata: languageName: node linkType: hard +"util-deprecate@npm:^1.0.1": + version: 1.0.2 + resolution: "util-deprecate@npm:1.0.2" + checksum: 10c0/41a5bdd214df2f6c3ecf8622745e4a366c4adced864bc3c833739791aeeeb1838119af7daed4ba36428114b5c67dcda034a79c882e97e43c03e66a4dd7389942 + languageName: node + linkType: hard + "uuid@npm:^10.0.0": version: 10.0.0 resolution: "uuid@npm:10.0.0"