fix: code review cleanup

- Add missing dependencies: ioredis, adm-zip, archiver, gray-matter, @types/multer, @types/archiver
- Fix import statements: use default imports for AdmZip, archiver, gray-matter
- Remove unused imports: ArrayMinSize
- Fix export types: use 'export type' for type-only exports
- Replace 'any' types with proper types:
  - AuthUser for user parameters
  - ExportEntry interface for entry data
  - unknown for frontmatter parsing parameters
  - Record<string, unknown> for dynamic objects
- Add security improvements:
  - File upload size limit: 50MB max
  - File type validation in FileInterceptor
  - Path traversal protection in zip extraction
  - Zip bomb protection: max 1000 files, 100MB uncompressed
- Fix exactOptionalPropertyTypes issues: use conditional spreading for optional fields
This commit is contained in:
Jason Woltje
2026-01-30 00:15:44 -06:00
parent c4c15ee87e
commit 10a812aedc
6 changed files with 463 additions and 35 deletions

View File

@@ -36,10 +36,14 @@
"@nestjs/websockets": "^11.1.12",
"@prisma/client": "^6.19.2",
"@types/marked": "^6.0.0",
"adm-zip": "^0.5.16",
"archiver": "^7.0.1",
"better-auth": "^1.4.17",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.3",
"gray-matter": "^4.0.3",
"highlight.js": "^11.11.1",
"ioredis": "^5.9.2",
"marked": "^17.0.1",
"marked-gfm-heading-id": "^4.1.3",
"marked-highlight": "^2.2.3",
@@ -61,7 +65,7 @@
"@types/archiver": "^7.0.0",
"@types/express": "^5.0.1",
"@types/highlight.js": "^10.1.0",
"@types/ioredis": "^5.0.0",
"@types/multer": "^2.0.0",
"@types/node": "^22.13.4",
"@types/sanitize-html": "^2.16.0",
"@vitest/coverage-v8": "^4.0.18",

View File

@@ -3,7 +3,6 @@ import {
IsOptional,
IsEnum,
IsArray,
ArrayMinSize,
} from "class-validator";
/**

View File

@@ -10,9 +10,5 @@ export {
RecentEntriesDto,
} from "./search-query.dto";
export { GraphQueryDto } from "./graph-query.dto";
export {
ExportQueryDto,
ExportFormat,
ImportResult,
ImportResponseDto,
} from "./import-export.dto";
export { ExportQueryDto, ExportFormat } from "./import-export.dto";
export type { ImportResult, ImportResponseDto } from "./import-export.dto";

View File

@@ -17,6 +17,7 @@ import { AuthGuard } from "../auth/guards/auth.guard";
import { WorkspaceGuard, PermissionGuard } from "../common/guards";
import { Workspace, Permission, RequirePermission } from "../common/decorators";
import { CurrentUser } from "../auth/decorators/current-user.decorator";
import type { AuthUser } from "../auth/types/better-auth-request.interface";
/**
* Controller for knowledge import/export endpoints
@@ -34,10 +35,42 @@ export class ImportExportController {
*/
@Post("import")
@RequirePermission(Permission.WORKSPACE_MEMBER)
@UseInterceptors(FileInterceptor("file"))
@UseInterceptors(
FileInterceptor("file", {
limits: {
fileSize: 50 * 1024 * 1024, // 50MB max file size
},
fileFilter: (_req, file, callback) => {
// Only accept .md and .zip files
const allowedMimeTypes = [
"text/markdown",
"application/zip",
"application/x-zip-compressed",
];
const allowedExtensions = [".md", ".zip"];
const fileExtension = file.originalname.toLowerCase().slice(
file.originalname.lastIndexOf(".")
);
if (
allowedMimeTypes.includes(file.mimetype) ||
allowedExtensions.includes(fileExtension)
) {
callback(null, true);
} else {
callback(
new BadRequestException(
"Invalid file type. Only .md and .zip files are accepted."
),
false
);
}
},
})
)
async importEntries(
@Workspace() workspaceId: string,
@CurrentUser() user: any,
@CurrentUser() user: AuthUser,
@UploadedFile() file: Express.Multer.File
): Promise<ImportResponseDto> {
if (!file) {

View File

@@ -1,14 +1,27 @@
import { Injectable, BadRequestException } from "@nestjs/common";
import { EntryStatus, Visibility } from "@prisma/client";
import * as archiver from "archiver";
import * as AdmZip from "adm-zip";
import * as matter from "gray-matter";
import archiver from "archiver";
import AdmZip from "adm-zip";
import matter from "gray-matter";
import { Readable } from "stream";
import { PrismaService } from "../../prisma/prisma.service";
import { KnowledgeService } from "../knowledge.service";
import type { ExportFormat, ImportResult } from "../dto";
import type { CreateEntryDto } from "../dto/create-entry.dto";
interface ExportEntry {
id: string;
slug: string;
title: string;
content: string;
summary: string | null;
status: EntryStatus;
visibility: Visibility;
tags: string[];
createdAt: Date;
updatedAt: Date;
}
/**
* Service for handling knowledge entry import/export operations
*/
@@ -94,14 +107,18 @@ export class ImportExportService {
}
// Build CreateEntryDto from frontmatter and content
const parsedStatus = this.parseStatus(frontmatter.status);
const parsedVisibility = this.parseVisibility(frontmatter.visibility);
const parsedTags = Array.isArray(frontmatter.tags) ? frontmatter.tags : undefined;
const createDto: CreateEntryDto = {
title: frontmatter.title || filename.replace(/\.md$/, ""),
content: markdownContent,
summary: frontmatter.summary,
status: this.parseStatus(frontmatter.status),
visibility: this.parseVisibility(frontmatter.visibility),
tags: Array.isArray(frontmatter.tags) ? frontmatter.tags : undefined,
changeNote: "Imported from markdown file",
...(frontmatter.summary && { summary: frontmatter.summary }),
...(parsedStatus && { status: parsedStatus }),
...(parsedVisibility && { visibility: parsedVisibility }),
...(parsedTags && { tags: parsedTags }),
};
// Create the entry
@@ -136,17 +153,57 @@ export class ImportExportService {
buffer: Buffer
): Promise<ImportResult[]> {
const results: ImportResult[] = [];
const MAX_FILES = 1000; // Prevent zip bomb attacks
const MAX_TOTAL_SIZE = 100 * 1024 * 1024; // 100MB total uncompressed
try {
const zip = new AdmZip(buffer);
const zipEntries = zip.getEntries();
// Security: Check for zip bombs
let totalUncompressedSize = 0;
let fileCount = 0;
for (const entry of zipEntries) {
if (!entry.isDirectory) {
fileCount++;
totalUncompressedSize += entry.header.size;
}
}
if (fileCount > MAX_FILES) {
throw new BadRequestException(
`Zip file contains too many files (${fileCount}). Maximum allowed: ${MAX_FILES}`
);
}
if (totalUncompressedSize > MAX_TOTAL_SIZE) {
throw new BadRequestException(
`Zip file is too large when uncompressed (${Math.round(totalUncompressedSize / 1024 / 1024)}MB). Maximum allowed: ${Math.round(MAX_TOTAL_SIZE / 1024 / 1024)}MB`
);
}
for (const zipEntry of zipEntries) {
// Skip directories and non-markdown files
if (zipEntry.isDirectory || !zipEntry.entryName.endsWith(".md")) {
continue;
}
// Security: Prevent path traversal attacks
const normalizedPath = zipEntry.entryName.replace(/\\/g, "/");
if (
normalizedPath.includes("..") ||
normalizedPath.startsWith("/") ||
normalizedPath.includes("//")
) {
results.push({
filename: zipEntry.entryName,
success: false,
error: "Invalid file path detected (potential path traversal)",
});
continue;
}
const content = zipEntry.getData().toString("utf-8");
const result = await this.importSingleMarkdown(
workspaceId,
@@ -218,8 +275,8 @@ export class ImportExportService {
private async fetchEntriesForExport(
workspaceId: string,
entryIds?: string[]
): Promise<any[]> {
const where: any = { workspaceId };
): Promise<ExportEntry[]> {
const where: Record<string, unknown> = { workspaceId };
if (entryIds && entryIds.length > 0) {
where.id = { in: entryIds };
@@ -256,7 +313,7 @@ export class ImportExportService {
/**
* Convert entry to markdown format with frontmatter
*/
private entryToMarkdown(entry: any): string {
private entryToMarkdown(entry: ExportEntry): string {
const frontmatter: Record<string, any> = {
title: entry.title,
status: entry.status,
@@ -290,7 +347,7 @@ export class ImportExportService {
/**
* Parse status from frontmatter
*/
private parseStatus(value: any): EntryStatus | undefined {
private parseStatus(value: unknown): EntryStatus | undefined {
if (!value) return undefined;
const statusMap: Record<string, EntryStatus> = {
DRAFT: EntryStatus.DRAFT,
@@ -303,7 +360,7 @@ export class ImportExportService {
/**
* Parse visibility from frontmatter
*/
private parseVisibility(value: any): Visibility | undefined {
private parseVisibility(value: unknown): Visibility | undefined {
if (!value) return undefined;
const visibilityMap: Record<string, Visibility> = {
PRIVATE: Visibility.PRIVATE,

365
pnpm-lock.yaml generated
View File

@@ -68,6 +68,12 @@ importers:
'@types/marked':
specifier: ^6.0.0
version: 6.0.0
adm-zip:
specifier: ^0.5.16
version: 0.5.16
archiver:
specifier: ^7.0.1
version: 7.0.1
better-auth:
specifier: ^1.4.17
version: 1.4.17(@prisma/client@6.19.2(prisma@6.19.2(magicast@0.3.5)(typescript@5.9.3))(typescript@5.9.3))(better-sqlite3@12.6.2)(drizzle-orm@0.41.0(@prisma/client@5.22.0(prisma@6.19.2(magicast@0.3.5)(typescript@5.9.3)))(@types/pg@8.16.0)(better-sqlite3@12.6.2)(kysely@0.28.10)(pg@8.17.2)(prisma@6.19.2(magicast@0.3.5)(typescript@5.9.3)))(next@16.1.6(@babel/core@7.28.6)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.17.2)(prisma@6.19.2(magicast@0.3.5)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@4.0.18(@types/node@22.19.7)(jiti@2.6.1)(jsdom@26.1.0)(terser@5.46.0)(tsx@4.21.0))
@@ -77,9 +83,15 @@ importers:
class-validator:
specifier: ^0.14.3
version: 0.14.3
gray-matter:
specifier: ^4.0.3
version: 4.0.3
highlight.js:
specifier: ^11.11.1
version: 11.11.1
ioredis:
specifier: ^5.9.2
version: 5.9.2
marked:
specifier: ^17.0.1
version: 17.0.1
@@ -138,9 +150,9 @@ importers:
'@types/highlight.js':
specifier: ^10.1.0
version: 10.1.0
'@types/ioredis':
specifier: ^5.0.0
version: 5.0.0
'@types/multer':
specifier: ^2.0.0
version: 2.0.0
'@types/node':
specifier: ^22.13.4
version: 22.19.7
@@ -1855,10 +1867,6 @@ packages:
'@types/http-errors@2.0.5':
resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==}
'@types/ioredis@5.0.0':
resolution: {integrity: sha512-zJbJ3FVE17CNl5KXzdeSPtdltc4tMT3TzC6fxQS0sQngkbFZ6h+0uTafsRqu+eSLIugf6Yb0Ea0SUuRr42Nk9g==}
deprecated: This is a stub types definition. ioredis provides its own type definitions, so you do not need this installed.
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
@@ -1866,6 +1874,9 @@ packages:
resolution: {integrity: sha512-jmjpa4BwUsmhxcfsgUit/7A9KbrC48Q0q8KvnY107ogcjGgTFDlIL3RpihNpx2Mu1hM4mdFQjoVc4O6JoGKHsA==}
deprecated: This is a stub types definition. marked provides its own type definitions, so you do not need this installed.
'@types/multer@2.0.0':
resolution: {integrity: sha512-C3Z9v9Evij2yST3RSBktxP9STm6OdMc5uR1xF1SGr98uv8dUlAL2hqwrZ3GVB3uyMyiegnscEK6PGtYvNrjTjw==}
'@types/node@22.19.7':
resolution: {integrity: sha512-MciR4AKGHWl7xwxkBa6xUGxQJ4VBOmPTF7sL+iGzuahOFaO0jHCsuEfS80pan1ef4gWId1oWOweIhrDEYLuaOw==}
@@ -2109,6 +2120,10 @@ packages:
'@xyflow/system@0.0.74':
resolution: {integrity: sha512-7v7B/PkiVrkdZzSbL+inGAo6tkR/WQHHG0/jhSvLQToCsfa8YubOGmBYd1s08tpKpihdHDZFwzQZeR69QSBb4Q==}
abort-controller@3.0.0:
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
engines: {node: '>=6.5'}
accepts@1.3.8:
resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==}
engines: {node: '>= 0.6'}
@@ -2133,6 +2148,10 @@ packages:
engines: {node: '>=0.4.0'}
hasBin: true
adm-zip@0.5.16:
resolution: {integrity: sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==}
engines: {node: '>=12.0'}
agent-base@7.1.4:
resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
engines: {node: '>= 14'}
@@ -2200,6 +2219,17 @@ packages:
append-field@1.0.0:
resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==}
archiver-utils@5.0.2:
resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==}
engines: {node: '>= 14'}
archiver@7.0.1:
resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==}
engines: {node: '>= 14'}
argparse@1.0.10:
resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
@@ -2220,9 +2250,28 @@ packages:
ast-v8-to-istanbul@0.3.10:
resolution: {integrity: sha512-p4K7vMz2ZSk3wN8l5o3y2bJAoZXT3VuJI5OLTATY/01CYWumWvwkUw0SqDBnNq6IiTO3qDa1eSQDibAV8g7XOQ==}
async@3.2.6:
resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==}
b4a@1.7.3:
resolution: {integrity: sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==}
peerDependencies:
react-native-b4a: '*'
peerDependenciesMeta:
react-native-b4a:
optional: true
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
bare-events@2.8.2:
resolution: {integrity: sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==}
peerDependencies:
bare-abort-controller: '*'
peerDependenciesMeta:
bare-abort-controller:
optional: true
base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
@@ -2329,12 +2378,19 @@ packages:
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
buffer-crc32@1.0.0:
resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==}
engines: {node: '>=8.0.0'}
buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
buffer@5.7.1:
resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
buffer@6.0.3:
resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
bundle-name@4.1.0:
resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==}
engines: {node: '>=18'}
@@ -2507,6 +2563,10 @@ packages:
resolution: {integrity: sha512-r1To31BQD5060QdkC+Iheai7gHwoSZobzunqkf2/kQ6xIAfJyrKNAFUwdKvkK7Qgu7pVTKQEa7ok7Ed3ycAJgg==}
engines: {node: '>= 6'}
compress-commons@6.0.2:
resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==}
engines: {node: '>= 14'}
concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
@@ -2565,6 +2625,15 @@ packages:
typescript:
optional: true
crc-32@1.2.2:
resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==}
engines: {node: '>=0.8'}
hasBin: true
crc32-stream@6.0.0:
resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==}
engines: {node: '>= 14'}
cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
@@ -3120,6 +3189,13 @@ packages:
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
engines: {node: '>= 0.6'}
event-target-shim@5.0.1:
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
engines: {node: '>=6'}
events-universal@1.0.1:
resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==}
events@3.3.0:
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
engines: {node: '>=0.8.x'}
@@ -3139,6 +3215,10 @@ packages:
exsolve@1.0.8:
resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==}
extend-shallow@2.0.1:
resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==}
engines: {node: '>=0.10.0'}
fast-check@3.23.2:
resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==}
engines: {node: '>=8.0.0'}
@@ -3152,6 +3232,9 @@ packages:
fast-equals@4.0.3:
resolution: {integrity: sha512-G3BSX9cfKttjr+2o1O22tYMLq0DPluZnYtq1rXumE1SpL/F/SLIfHx08WYQoWSIpeMYf8sRbJ8++71+v6Pnxfg==}
fast-fifo@1.3.2:
resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==}
fast-json-stable-stringify@2.1.0:
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
@@ -3287,6 +3370,10 @@ packages:
graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
gray-matter@4.0.3:
resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==}
engines: {node: '>=6.0'}
hachure-fill@0.5.2:
resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==}
@@ -3388,6 +3475,10 @@ packages:
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
hasBin: true
is-extendable@0.1.1:
resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==}
engines: {node: '>=0.10.0'}
is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
@@ -3419,6 +3510,10 @@ packages:
is-promise@4.0.0:
resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==}
is-stream@2.0.1:
resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
engines: {node: '>=8'}
is-unicode-supported@0.1.0:
resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==}
engines: {node: '>=10'}
@@ -3427,6 +3522,9 @@ packages:
resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==}
engines: {node: '>=16'}
isarray@1.0.0:
resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
@@ -3470,6 +3568,10 @@ packages:
js-tokens@9.0.1:
resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==}
js-yaml@3.14.2:
resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==}
hasBin: true
js-yaml@4.1.1:
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
hasBin: true
@@ -3524,6 +3626,10 @@ packages:
khroma@2.1.0:
resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==}
kind-of@6.0.3:
resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
engines: {node: '>=0.10.0'}
kleur@3.0.3:
resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
engines: {node: '>=6'}
@@ -3542,6 +3648,10 @@ packages:
layout-base@2.0.1:
resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==}
lazystream@1.0.1:
resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==}
engines: {node: '>= 0.6.3'}
levn@0.4.1:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
@@ -3720,6 +3830,10 @@ packages:
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
minimatch@5.1.6:
resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
engines: {node: '>=10'}
minimatch@9.0.5:
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
engines: {node: '>=16 || 14 >=14.17'}
@@ -3815,6 +3929,10 @@ packages:
node-releases@2.0.27:
resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==}
normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
nwsapi@2.2.23:
resolution: {integrity: sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==}
@@ -4055,6 +4173,13 @@ packages:
typescript:
optional: true
process-nextick-args@2.0.1:
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
process@0.11.10:
resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
engines: {node: '>= 0.6.0'}
prompts@2.4.2:
resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
engines: {node: '>= 6'}
@@ -4135,10 +4260,20 @@ packages:
resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==}
engines: {node: '>=0.10.0'}
readable-stream@2.3.8:
resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
readable-stream@3.6.2:
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
engines: {node: '>= 6'}
readable-stream@4.7.0:
resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
readdir-glob@1.1.3:
resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==}
readdirp@4.1.2:
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
engines: {node: '>= 14.18.0'}
@@ -4217,6 +4352,9 @@ packages:
rxjs@7.8.2:
resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==}
safe-buffer@5.1.2:
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
safe-buffer@5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
@@ -4241,6 +4379,10 @@ packages:
resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==}
engines: {node: '>= 10.13.0'}
section-matter@1.0.0:
resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==}
engines: {node: '>=4'}
semver@6.3.1:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
@@ -4352,6 +4494,9 @@ packages:
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
engines: {node: '>= 10.x'}
sprintf-js@1.0.3:
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
stackback@0.0.2:
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
@@ -4369,6 +4514,9 @@ packages:
resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
engines: {node: '>=10.0.0'}
streamx@2.23.0:
resolution: {integrity: sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==}
string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
@@ -4377,6 +4525,9 @@ packages:
resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
engines: {node: '>=12'}
string_decoder@1.1.1:
resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
string_decoder@1.3.0:
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
@@ -4388,6 +4539,10 @@ packages:
resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==}
engines: {node: '>=12'}
strip-bom-string@1.0.0:
resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==}
engines: {node: '>=0.10.0'}
strip-bom@3.0.0:
resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
engines: {node: '>=4'}
@@ -4457,6 +4612,9 @@ packages:
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
engines: {node: '>=6'}
tar-stream@3.1.7:
resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==}
terser-webpack-plugin@5.3.16:
resolution: {integrity: sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==}
engines: {node: '>= 10.13.0'}
@@ -4482,6 +4640,9 @@ packages:
resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==}
engines: {node: '>=18'}
text-decoder@1.2.3:
resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==}
tinybench@2.9.0:
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
@@ -4959,6 +5120,10 @@ packages:
resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==}
engines: {node: '>=18'}
zip-stream@6.0.1:
resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==}
engines: {node: '>= 14'}
zod@4.3.6:
resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==}
@@ -6516,18 +6681,16 @@ snapshots:
'@types/http-errors@2.0.5': {}
'@types/ioredis@5.0.0':
dependencies:
ioredis: 5.9.2
transitivePeerDependencies:
- supports-color
'@types/json-schema@7.0.15': {}
'@types/marked@6.0.0':
dependencies:
marked: 17.0.1
'@types/multer@2.0.0':
dependencies:
'@types/express': 5.0.6
'@types/node@22.19.7':
dependencies:
undici-types: 6.21.0
@@ -6913,6 +7076,10 @@ snapshots:
d3-selection: 3.0.0
d3-zoom: 3.0.0
abort-controller@3.0.0:
dependencies:
event-target-shim: 5.0.1
accepts@1.3.8:
dependencies:
mime-types: 2.1.35
@@ -6933,6 +7100,8 @@ snapshots:
acorn@8.15.0: {}
adm-zip@0.5.16: {}
agent-base@7.1.4: {}
ajv-formats@2.1.1(ajv@8.17.1):
@@ -6984,6 +7153,33 @@ snapshots:
append-field@1.0.0: {}
archiver-utils@5.0.2:
dependencies:
glob: 10.5.0
graceful-fs: 4.2.11
is-stream: 2.0.1
lazystream: 1.0.1
lodash: 4.17.23
normalize-path: 3.0.0
readable-stream: 4.7.0
archiver@7.0.1:
dependencies:
archiver-utils: 5.0.2
async: 3.2.6
buffer-crc32: 1.0.0
readable-stream: 4.7.0
readdir-glob: 1.1.3
tar-stream: 3.1.7
zip-stream: 6.0.1
transitivePeerDependencies:
- bare-abort-controller
- react-native-b4a
argparse@1.0.10:
dependencies:
sprintf-js: 1.0.3
argparse@2.0.1: {}
aria-query@5.3.0:
@@ -7002,8 +7198,14 @@ snapshots:
estree-walker: 3.0.3
js-tokens: 9.0.1
async@3.2.6: {}
b4a@1.7.3: {}
balanced-match@1.0.2: {}
bare-events@2.8.2: {}
base64-js@1.5.1: {}
base64id@2.0.0: {}
@@ -7140,6 +7342,8 @@ snapshots:
node-releases: 2.0.27
update-browserslist-db: 1.2.3(browserslist@4.28.1)
buffer-crc32@1.0.0: {}
buffer-from@1.1.2: {}
buffer@5.7.1:
@@ -7147,6 +7351,11 @@ snapshots:
base64-js: 1.5.1
ieee754: 1.2.1
buffer@6.0.3:
dependencies:
base64-js: 1.5.1
ieee754: 1.2.1
bundle-name@4.1.0:
dependencies:
run-applescript: 7.1.0
@@ -7323,6 +7532,14 @@ snapshots:
core-util-is: 1.0.3
esprima: 4.0.1
compress-commons@6.0.2:
dependencies:
crc-32: 1.2.2
crc32-stream: 6.0.0
is-stream: 2.0.1
normalize-path: 3.0.0
readable-stream: 4.7.0
concat-map@0.0.1: {}
concat-stream@2.0.0:
@@ -7372,6 +7589,13 @@ snapshots:
optionalDependencies:
typescript: 5.9.3
crc-32@1.2.2: {}
crc32-stream@6.0.0:
dependencies:
crc-32: 1.2.2
readable-stream: 4.7.0
cross-spawn@7.0.6:
dependencies:
path-key: 3.1.1
@@ -7888,6 +8112,14 @@ snapshots:
etag@1.8.1: {}
event-target-shim@5.0.1: {}
events-universal@1.0.1:
dependencies:
bare-events: 2.8.2
transitivePeerDependencies:
- bare-abort-controller
events@3.3.0: {}
expand-template@2.0.3: {}
@@ -7929,6 +8161,10 @@ snapshots:
exsolve@1.0.8: {}
extend-shallow@2.0.1:
dependencies:
is-extendable: 0.1.1
fast-check@3.23.2:
dependencies:
pure-rand: 6.1.0
@@ -7939,6 +8175,8 @@ snapshots:
fast-equals@4.0.3: {}
fast-fifo@1.3.2: {}
fast-json-stable-stringify@2.1.0: {}
fast-levenshtein@2.0.6: {}
@@ -8094,6 +8332,13 @@ snapshots:
graceful-fs@4.2.11: {}
gray-matter@4.0.3:
dependencies:
js-yaml: 3.14.2
kind-of: 6.0.3
section-matter: 1.0.0
strip-bom-string: 1.0.0
hachure-fill@0.5.2: {}
has-flag@4.0.0: {}
@@ -8192,6 +8437,8 @@ snapshots:
is-docker@3.0.0: {}
is-extendable@0.1.1: {}
is-extglob@2.1.1: {}
is-fullwidth-code-point@3.0.0: {}
@@ -8212,12 +8459,16 @@ snapshots:
is-promise@4.0.0: {}
is-stream@2.0.1: {}
is-unicode-supported@0.1.0: {}
is-wsl@3.1.0:
dependencies:
is-inside-container: 1.0.0
isarray@1.0.0: {}
isexe@2.0.0: {}
istanbul-lib-coverage@3.2.2: {}
@@ -8263,6 +8514,11 @@ snapshots:
js-tokens@9.0.1: {}
js-yaml@3.14.2:
dependencies:
argparse: 1.0.10
esprima: 4.0.1
js-yaml@4.1.1:
dependencies:
argparse: 2.0.1
@@ -8326,6 +8582,8 @@ snapshots:
khroma@2.1.0: {}
kind-of@6.0.3: {}
kleur@3.0.3: {}
kysely@0.28.10: {}
@@ -8342,6 +8600,10 @@ snapshots:
layout-base@2.0.1: {}
lazystream@1.0.1:
dependencies:
readable-stream: 2.3.8
levn@0.4.1:
dependencies:
prelude-ls: 1.2.1
@@ -8502,6 +8764,10 @@ snapshots:
dependencies:
brace-expansion: 1.1.12
minimatch@5.1.6:
dependencies:
brace-expansion: 2.0.2
minimatch@9.0.5:
dependencies:
brace-expansion: 2.0.2
@@ -8589,6 +8855,8 @@ snapshots:
node-releases@2.0.27: {}
normalize-path@3.0.0: {}
nwsapi@2.2.23: {}
nypm@0.6.4:
@@ -8832,6 +9100,10 @@ snapshots:
transitivePeerDependencies:
- magicast
process-nextick-args@2.0.1: {}
process@0.11.10: {}
prompts@2.4.2:
dependencies:
kleur: 3.0.3
@@ -8924,12 +9196,34 @@ snapshots:
react@19.2.4: {}
readable-stream@2.3.8:
dependencies:
core-util-is: 1.0.3
inherits: 2.0.4
isarray: 1.0.0
process-nextick-args: 2.0.1
safe-buffer: 5.1.2
string_decoder: 1.1.1
util-deprecate: 1.0.2
readable-stream@3.6.2:
dependencies:
inherits: 2.0.4
string_decoder: 1.3.0
util-deprecate: 1.0.2
readable-stream@4.7.0:
dependencies:
abort-controller: 3.0.0
buffer: 6.0.3
events: 3.3.0
process: 0.11.10
string_decoder: 1.3.0
readdir-glob@1.1.3:
dependencies:
minimatch: 5.1.6
readdirp@4.1.2: {}
readdirp@5.0.0: {}
@@ -9028,6 +9322,8 @@ snapshots:
dependencies:
tslib: 2.8.1
safe-buffer@5.1.2: {}
safe-buffer@5.2.1: {}
safer-buffer@2.1.2: {}
@@ -9060,6 +9356,11 @@ snapshots:
ajv-formats: 2.1.1(ajv@8.17.1)
ajv-keywords: 5.1.0(ajv@8.17.1)
section-matter@1.0.0:
dependencies:
extend-shallow: 2.0.1
kind-of: 6.0.3
semver@6.3.1: {}
semver@7.7.3: {}
@@ -9235,6 +9536,8 @@ snapshots:
split2@4.2.0: {}
sprintf-js@1.0.3: {}
stackback@0.0.2: {}
standard-as-callback@2.1.0: {}
@@ -9245,6 +9548,15 @@ snapshots:
streamsearch@1.1.0: {}
streamx@2.23.0:
dependencies:
events-universal: 1.0.1
fast-fifo: 1.3.2
text-decoder: 1.2.3
transitivePeerDependencies:
- bare-abort-controller
- react-native-b4a
string-width@4.2.3:
dependencies:
emoji-regex: 8.0.0
@@ -9257,6 +9569,10 @@ snapshots:
emoji-regex: 9.2.2
strip-ansi: 7.1.2
string_decoder@1.1.1:
dependencies:
safe-buffer: 5.1.2
string_decoder@1.3.0:
dependencies:
safe-buffer: 5.2.1
@@ -9269,6 +9585,8 @@ snapshots:
dependencies:
ansi-regex: 6.2.2
strip-bom-string@1.0.0: {}
strip-bom@3.0.0: {}
strip-indent@3.0.0:
@@ -9329,6 +9647,15 @@ snapshots:
inherits: 2.0.4
readable-stream: 3.6.2
tar-stream@3.1.7:
dependencies:
b4a: 1.7.3
fast-fifo: 1.3.2
streamx: 2.23.0
transitivePeerDependencies:
- bare-abort-controller
- react-native-b4a
terser-webpack-plugin@5.3.16(@swc/core@1.15.11)(webpack@5.104.1(@swc/core@1.15.11)):
dependencies:
'@jridgewell/trace-mapping': 0.3.31
@@ -9353,6 +9680,12 @@ snapshots:
glob: 10.5.0
minimatch: 9.0.5
text-decoder@1.2.3:
dependencies:
b4a: 1.7.3
transitivePeerDependencies:
- react-native-b4a
tinybench@2.9.0: {}
tinyexec@0.3.2: {}
@@ -9795,6 +10128,12 @@ snapshots:
yoctocolors@2.1.2: {}
zip-stream@6.0.1:
dependencies:
archiver-utils: 5.0.2
compress-commons: 6.0.2
readable-stream: 4.7.0
zod@4.3.6: {}
zustand@4.5.7(@types/react@19.2.10)(react@19.2.4):