mirror of
https://github.com/docmost/docmost.git
synced 2026-05-07 06:23:06 +08:00
Merge branch 'main' into tiptap3-migration
This commit is contained in:
+7
-1
@@ -46,4 +46,10 @@ DRAWIO_URL=
|
||||
DISABLE_TELEMETRY=false
|
||||
|
||||
# Enable debug logging in production (default: false)
|
||||
DEBUG_MODE=false
|
||||
DEBUG_MODE=false
|
||||
|
||||
# Log database queries
|
||||
DEBUG_DB=false
|
||||
|
||||
# Log http requests
|
||||
LOG_HTTP=false
|
||||
|
||||
@@ -74,11 +74,13 @@
|
||||
"jsonwebtoken": "^9.0.3",
|
||||
"kysely": "^0.28.2",
|
||||
"kysely-migration-cli": "^0.4.2",
|
||||
"kysely-postgres-js": "^3.0.0",
|
||||
"ldapts": "^7.4.0",
|
||||
"mammoth": "^1.11.0",
|
||||
"mime-types": "^2.1.35",
|
||||
"nanoid": "3.3.11",
|
||||
"nestjs-kysely": "^1.2.0",
|
||||
"nestjs-pino": "^4.5.0",
|
||||
"nodemailer": "^7.0.12",
|
||||
"openid-client": "^5.7.1",
|
||||
"otpauth": "^9.4.1",
|
||||
@@ -86,9 +88,11 @@
|
||||
"passport-google-oauth20": "^2.0.0",
|
||||
"passport-jwt": "^4.0.1",
|
||||
"pdfjs-dist": "^5.4.394",
|
||||
"pg": "^8.16.3",
|
||||
"pg-tsquery": "^8.4.2",
|
||||
"pgvector": "^0.2.1",
|
||||
"postgres": "^3.4.8",
|
||||
"pino-http": "^11.0.0",
|
||||
"pino-pretty": "^13.1.3",
|
||||
"postmark": "^4.0.5",
|
||||
"react": "^18.3.1",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
@@ -116,7 +120,6 @@
|
||||
"@types/nodemailer": "^6.4.17",
|
||||
"@types/passport-google-oauth20": "^2.0.16",
|
||||
"@types/passport-jwt": "^4.0.1",
|
||||
"@types/pg": "^8.11.11",
|
||||
"@types/supertest": "^6.0.2",
|
||||
"@types/ws": "^8.5.14",
|
||||
"@types/yauzl": "^2.10.3",
|
||||
|
||||
@@ -18,6 +18,7 @@ import { SecurityModule } from './integrations/security/security.module';
|
||||
import { TelemetryModule } from './integrations/telemetry/telemetry.module';
|
||||
import { RedisModule } from '@nestjs-labs/nestjs-ioredis';
|
||||
import { RedisConfigService } from './integrations/redis/redis-config.service';
|
||||
import { LoggerModule } from './common/logger/logger.module';
|
||||
|
||||
const enterpriseModules = [];
|
||||
try {
|
||||
@@ -35,6 +36,7 @@ try {
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
LoggerModule,
|
||||
CoreModule,
|
||||
DatabaseModule,
|
||||
EnvironmentModule,
|
||||
|
||||
@@ -8,9 +8,11 @@ import { QueueModule } from '../../integrations/queue/queue.module';
|
||||
import { EventEmitterModule } from '@nestjs/event-emitter';
|
||||
import { HealthModule } from '../../integrations/health/health.module';
|
||||
import { CollaborationController } from './collaboration.controller';
|
||||
import { LoggerModule } from '../../common/logger/logger.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
LoggerModule,
|
||||
DatabaseModule,
|
||||
EnvironmentModule,
|
||||
CollaborationModule,
|
||||
|
||||
@@ -5,8 +5,8 @@ import {
|
||||
NestFastifyApplication,
|
||||
} from '@nestjs/platform-fastify';
|
||||
import { TransformHttpResponseInterceptor } from '../../common/interceptors/http-response.interceptor';
|
||||
import { InternalLogFilter } from '../../common/logger/internal-log-filter';
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { Logger as PinoLogger } from 'nestjs-pino';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create<NestFastifyApplication>(
|
||||
@@ -17,10 +17,12 @@ async function bootstrap() {
|
||||
maxParamLength: 500,
|
||||
}),
|
||||
{
|
||||
logger: new InternalLogFilter(),
|
||||
bufferLogs: true,
|
||||
},
|
||||
);
|
||||
|
||||
app.useLogger(app.get(PinoLogger));
|
||||
|
||||
app.setGlobalPrefix('api', { exclude: ['/'] });
|
||||
|
||||
app.enableCors();
|
||||
|
||||
@@ -2,6 +2,7 @@ import * as path from 'path';
|
||||
import * as bcrypt from 'bcrypt';
|
||||
import { sanitize } from 'sanitize-filename-ts';
|
||||
import { FastifyRequest } from 'fastify';
|
||||
import { Readable, Transform } from 'stream';
|
||||
|
||||
export const envPath = path.resolve(process.cwd(), '..', '..', '.env');
|
||||
|
||||
@@ -98,3 +99,38 @@ export function hasLicenseOrEE(opts: {
|
||||
const { licenseKey, plan, isCloud } = opts;
|
||||
return Boolean(licenseKey) || (isCloud && plan === 'business');
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes a database URL for postgres.js compatibility.
|
||||
* - Removes `sslmode=no-verify` (not supported by postgres.js), keeps other sslmode values
|
||||
* - Removes `schema` parameter (has no effect via connection string)
|
||||
* Note: If we don't strip them, the connection will fail
|
||||
*/
|
||||
export function normalizePostgresUrl(url: string): string {
|
||||
const parsed = new URL(url);
|
||||
const newParams = new URLSearchParams();
|
||||
|
||||
for (const [key, value] of parsed.searchParams) {
|
||||
if (key === 'sslmode' && value === 'no-verify') continue;
|
||||
if (key === 'schema') continue;
|
||||
newParams.append(key, value);
|
||||
}
|
||||
|
||||
parsed.search = newParams.toString();
|
||||
return parsed.toString();
|
||||
}
|
||||
|
||||
export function createByteCountingStream(source: Readable) {
|
||||
let bytesRead = 0;
|
||||
const stream = new Transform({
|
||||
transform(chunk, encoding, callback) {
|
||||
bytesRead += chunk.length;
|
||||
callback(null, chunk);
|
||||
},
|
||||
});
|
||||
|
||||
source.pipe(stream);
|
||||
source.on('error', (err) => stream.emit('error', err));
|
||||
|
||||
return { stream, getBytesRead: () => bytesRead };
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { LoggerModule as PinoLoggerModule } from 'nestjs-pino';
|
||||
import { createPinoConfig } from './pino.config';
|
||||
|
||||
@Module({
|
||||
imports: [PinoLoggerModule.forRoot(createPinoConfig())],
|
||||
exports: [PinoLoggerModule],
|
||||
})
|
||||
export class LoggerModule {}
|
||||
@@ -0,0 +1,77 @@
|
||||
import { Params } from 'nestjs-pino';
|
||||
import { stdTimeFunctions } from 'pino';
|
||||
|
||||
const CONTEXTS_TO_IGNORE = [
|
||||
'InstanceLoader',
|
||||
'RoutesResolver',
|
||||
'RouterExplorer',
|
||||
'WebSocketsController',
|
||||
];
|
||||
|
||||
export function createPinoConfig(): Params {
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
const isDebugMode = process.env.DEBUG_MODE === 'true';
|
||||
const logHttp = process.env.LOG_HTTP === 'true';
|
||||
|
||||
const level = isProduction && !isDebugMode ? 'info' : 'debug';
|
||||
|
||||
return {
|
||||
pinoHttp: {
|
||||
level,
|
||||
timestamp: stdTimeFunctions.isoTime,
|
||||
transport: !isProduction
|
||||
? {
|
||||
target: 'pino-pretty',
|
||||
options: {
|
||||
colorize: true,
|
||||
singleLine: true,
|
||||
translateTime: 'SYS:standard',
|
||||
ignore: 'pid,hostname',
|
||||
},
|
||||
}
|
||||
: undefined,
|
||||
formatters: {
|
||||
level: (label) => ({ level: label }),
|
||||
log: (object: Record<string, unknown>) => {
|
||||
if (isProduction && !isDebugMode) {
|
||||
const context = object['context'] as string | undefined;
|
||||
if (context && CONTEXTS_TO_IGNORE.includes(context)) {
|
||||
return { filtered: true };
|
||||
}
|
||||
}
|
||||
return object;
|
||||
},
|
||||
},
|
||||
serializers: {
|
||||
req: (req) => {
|
||||
const forwardedFor = req.headers?.['x-forwarded-for'];
|
||||
const ip =
|
||||
req.headers?.['cf-connecting-ip'] ||
|
||||
(typeof forwardedFor === 'string' ? forwardedFor.split(',')[0]?.trim() : undefined) ||
|
||||
req.remoteAddress;
|
||||
|
||||
return {
|
||||
method: req.method,
|
||||
url: req.url,
|
||||
ip,
|
||||
userAgent: req.headers?.['user-agent'],
|
||||
};
|
||||
},
|
||||
res: (res) => ({
|
||||
statusCode: res.statusCode,
|
||||
}),
|
||||
},
|
||||
customLogLevel: (_req, res, err) => {
|
||||
if (res.statusCode >= 500 || err) return 'error';
|
||||
if (res.statusCode >= 400) return 'warn';
|
||||
return 'info';
|
||||
},
|
||||
autoLogging: logHttp
|
||||
? {
|
||||
ignore: (req) =>
|
||||
req.url === '/api/health' || req.url === '/api/health/live',
|
||||
}
|
||||
: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -5,15 +5,17 @@ import { sanitizeFileName } from '../../common/helpers';
|
||||
import * as sharp from 'sharp';
|
||||
|
||||
export interface PreparedFile {
|
||||
buffer: Buffer;
|
||||
buffer?: Buffer;
|
||||
fileName: string;
|
||||
fileSize: number;
|
||||
fileExtension: string;
|
||||
mimeType: string;
|
||||
multiPartFile?: MultipartFile;
|
||||
}
|
||||
|
||||
export async function prepareFile(
|
||||
filePromise: Promise<MultipartFile>,
|
||||
options: { skipBuffer?: boolean } = {},
|
||||
): Promise<PreparedFile> {
|
||||
const file = await filePromise;
|
||||
|
||||
@@ -22,10 +24,16 @@ export async function prepareFile(
|
||||
}
|
||||
|
||||
try {
|
||||
const buffer = await file.toBuffer();
|
||||
let buffer: Buffer | undefined;
|
||||
let fileSize = 0;
|
||||
|
||||
if (!options.skipBuffer) {
|
||||
buffer = await file.toBuffer();
|
||||
fileSize = buffer.length;
|
||||
}
|
||||
|
||||
const sanitizedFilename = sanitizeFileName(file.filename);
|
||||
const fileName = sanitizedFilename.slice(0, 255);
|
||||
const fileSize = buffer.length;
|
||||
const fileExtension = path.extname(file.filename).toLowerCase();
|
||||
|
||||
return {
|
||||
@@ -34,6 +42,7 @@ export async function prepareFile(
|
||||
fileSize,
|
||||
fileExtension,
|
||||
mimeType: file.mimetype,
|
||||
multiPartFile: file,
|
||||
};
|
||||
} catch (error) {
|
||||
throw error;
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
Logger,
|
||||
NotFoundException,
|
||||
} from '@nestjs/common';
|
||||
import { Readable } from 'stream';
|
||||
import { StorageService } from '../../../integrations/storage/storage.service';
|
||||
import { MultipartFile } from '@fastify/multipart';
|
||||
import {
|
||||
@@ -26,6 +27,7 @@ import { SpaceRepo } from '@docmost/db/repos/space/space.repo';
|
||||
import { InjectQueue } from '@nestjs/bullmq';
|
||||
import { QueueJob, QueueName } from '../../../integrations/queue/constants';
|
||||
import { Queue } from 'bullmq';
|
||||
import { createByteCountingStream } from '../../../common/helpers/utils';
|
||||
|
||||
@Injectable()
|
||||
export class AttachmentService {
|
||||
@@ -49,7 +51,9 @@ export class AttachmentService {
|
||||
attachmentId?: string;
|
||||
}) {
|
||||
const { filePromise, pageId, spaceId, userId, workspaceId } = opts;
|
||||
const preparedFile: PreparedFile = await prepareFile(filePromise);
|
||||
const preparedFile: PreparedFile = await prepareFile(filePromise, {
|
||||
skipBuffer: true,
|
||||
});
|
||||
|
||||
let isUpdate = false;
|
||||
let attachmentId = null;
|
||||
@@ -81,7 +85,14 @@ export class AttachmentService {
|
||||
|
||||
const filePath = `${getAttachmentFolderPath(AttachmentType.File, workspaceId)}/${attachmentId}/${preparedFile.fileName}`;
|
||||
|
||||
await this.uploadToDrive(filePath, preparedFile.buffer);
|
||||
const { stream, getBytesRead } = createByteCountingStream(
|
||||
preparedFile.multiPartFile.file,
|
||||
);
|
||||
|
||||
await this.uploadToDrive(filePath, stream);
|
||||
|
||||
// Update fileSize from the consumed stream
|
||||
preparedFile.fileSize = getBytesRead();
|
||||
|
||||
let attachment: Attachment = null;
|
||||
try {
|
||||
@@ -142,7 +153,10 @@ export class AttachmentService {
|
||||
const preparedFile: PreparedFile = await prepareFile(filePromise);
|
||||
validateFileType(preparedFile.fileExtension, validImageExtensions);
|
||||
|
||||
const processedBuffer = await compressAndResizeIcon(preparedFile.buffer, type);
|
||||
const processedBuffer = await compressAndResizeIcon(
|
||||
preparedFile.buffer,
|
||||
type,
|
||||
);
|
||||
preparedFile.buffer = processedBuffer;
|
||||
preparedFile.fileSize = processedBuffer.length;
|
||||
preparedFile.fileName = uuid4() + preparedFile.fileExtension;
|
||||
@@ -232,9 +246,9 @@ export class AttachmentService {
|
||||
}
|
||||
}
|
||||
|
||||
async uploadToDrive(filePath: string, fileBuffer: any) {
|
||||
async uploadToDrive(filePath: string, fileContent: Buffer | Readable) {
|
||||
try {
|
||||
await this.storageService.upload(filePath, fileBuffer);
|
||||
await this.storageService.upload(filePath, fileContent);
|
||||
} catch (err) {
|
||||
this.logger.error('Error uploading file to drive:', err);
|
||||
throw new BadRequestException('Error uploading file to drive');
|
||||
|
||||
@@ -7,8 +7,7 @@ import {
|
||||
} from '@nestjs/common';
|
||||
import { InjectKysely, KyselyModule } from 'nestjs-kysely';
|
||||
import { EnvironmentService } from '../integrations/environment/environment.service';
|
||||
import { CamelCasePlugin, LogEvent, PostgresDialect, sql } from 'kysely';
|
||||
import { Pool, types } from 'pg';
|
||||
import { CamelCasePlugin, LogEvent, sql } from 'kysely';
|
||||
import { GroupRepo } from '@docmost/db/repos/group/group.repo';
|
||||
import { WorkspaceRepo } from '@docmost/db/repos/workspace/workspace.repo';
|
||||
import { UserRepo } from '@docmost/db/repos/user/user.repo';
|
||||
@@ -26,9 +25,9 @@ import { UserTokenRepo } from './repos/user-token/user-token.repo';
|
||||
import { BacklinkRepo } from '@docmost/db/repos/backlink/backlink.repo';
|
||||
import { ShareRepo } from '@docmost/db/repos/share/share.repo';
|
||||
import { PageListener } from '@docmost/db/listeners/page.listener';
|
||||
|
||||
// https://github.com/brianc/node-postgres/issues/811
|
||||
types.setTypeParser(types.builtins.INT8, (val) => Number(val));
|
||||
import { PostgresJSDialect } from 'kysely-postgres-js';
|
||||
import * as postgres from 'postgres';
|
||||
import { normalizePostgresUrl } from '../common/helpers';
|
||||
|
||||
@Global()
|
||||
@Module({
|
||||
@@ -37,26 +36,30 @@ types.setTypeParser(types.builtins.INT8, (val) => Number(val));
|
||||
imports: [],
|
||||
inject: [EnvironmentService],
|
||||
useFactory: (environmentService: EnvironmentService) => ({
|
||||
dialect: new PostgresDialect({
|
||||
pool: new Pool({
|
||||
connectionString: environmentService.getDatabaseURL(),
|
||||
max: environmentService.getDatabaseMaxPool(),
|
||||
}).on('error', (err) => {
|
||||
console.error('Database error:', err.message);
|
||||
}),
|
||||
dialect: new PostgresJSDialect({
|
||||
postgres: postgres(
|
||||
normalizePostgresUrl(environmentService.getDatabaseURL()),
|
||||
{
|
||||
max: environmentService.getDatabaseMaxPool(),
|
||||
onnotice: () => {},
|
||||
types: {
|
||||
bigint: {
|
||||
to: 20,
|
||||
from: [20, 1700],
|
||||
serialize: (value: number) => value.toString(),
|
||||
parse: (value: string) => Number.parseInt(value),
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
}),
|
||||
plugins: [new CamelCasePlugin()],
|
||||
log: (event: LogEvent) => {
|
||||
if (environmentService.getNodeEnv() !== 'development') return;
|
||||
const logger = new Logger(DatabaseModule.name);
|
||||
if (event.level) {
|
||||
if (process.env.DEBUG_DB?.toLowerCase() === 'true') {
|
||||
logger.debug(event.query.sql);
|
||||
logger.debug('query time: ' + event.queryDurationMillis + ' ms');
|
||||
//if (event.query.parameters.length > 0) {
|
||||
// logger.debug('parameters: ' + event.query.parameters);
|
||||
//}
|
||||
}
|
||||
if (process.env.DEBUG_DB?.toLowerCase() === 'true') {
|
||||
logger.debug(event.query.sql);
|
||||
logger.debug('query time: ' + event.queryDurationMillis + ' ms');
|
||||
}
|
||||
},
|
||||
}),
|
||||
|
||||
@@ -1,25 +1,19 @@
|
||||
import * as path from 'path';
|
||||
import { promises as fs } from 'fs';
|
||||
import pg from 'pg';
|
||||
import {
|
||||
Kysely,
|
||||
Migrator,
|
||||
PostgresDialect,
|
||||
FileMigrationProvider,
|
||||
} from 'kysely';
|
||||
import { Kysely, Migrator, FileMigrationProvider } from 'kysely';
|
||||
import { run } from 'kysely-migration-cli';
|
||||
import * as dotenv from 'dotenv';
|
||||
import { envPath } from '../common/helpers/utils';
|
||||
import { envPath, normalizePostgresUrl } from '../common/helpers';
|
||||
import { PostgresJSDialect } from 'kysely-postgres-js';
|
||||
import postgres from 'postgres';
|
||||
|
||||
dotenv.config({ path: envPath });
|
||||
|
||||
const migrationFolder = path.join(__dirname, './migrations');
|
||||
|
||||
const db = new Kysely<any>({
|
||||
dialect: new PostgresDialect({
|
||||
pool: new pg.Pool({
|
||||
connectionString: process.env.DATABASE_URL,
|
||||
}) as any,
|
||||
dialect: new PostgresJSDialect({
|
||||
postgres: postgres(normalizePostgresUrl(process.env.DATABASE_URL)),
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
+1
-1
Submodule apps/server/src/ee updated: fce3e9e945...b6844b019c
@@ -10,7 +10,11 @@ import {
|
||||
} from '../../../collaboration/collaboration.util';
|
||||
import { InjectKysely } from 'nestjs-kysely';
|
||||
import { KyselyDB } from '@docmost/db/types/kysely.types';
|
||||
import { generateSlugId, sanitizeFileName } from '../../../common/helpers';
|
||||
import {
|
||||
generateSlugId,
|
||||
sanitizeFileName,
|
||||
createByteCountingStream,
|
||||
} from '../../../common/helpers';
|
||||
import { generateJitteredKeyBetween } from 'fractional-indexing-jittered';
|
||||
import { TiptapTransformer } from '@hocuspocus/transformer';
|
||||
import * as Y from 'yjs';
|
||||
@@ -173,15 +177,24 @@ export class ImportService {
|
||||
};
|
||||
}
|
||||
|
||||
async getNewPagePosition(spaceId: string): Promise<string> {
|
||||
const lastPage = await this.db
|
||||
async getNewPagePosition(
|
||||
spaceId: string,
|
||||
parentPageId?: string,
|
||||
): Promise<string> {
|
||||
let query = this.db
|
||||
.selectFrom('pages')
|
||||
.select(['id', 'position'])
|
||||
.where('spaceId', '=', spaceId)
|
||||
.orderBy('position', (ob) => ob.collate('C').desc())
|
||||
.limit(1)
|
||||
.where('parentPageId', 'is', null)
|
||||
.executeTakeFirst();
|
||||
.limit(1);
|
||||
|
||||
if (parentPageId) {
|
||||
query = query.where('parentPageId', '=', parentPageId);
|
||||
} else {
|
||||
query = query.where('parentPageId', 'is', null);
|
||||
}
|
||||
|
||||
const lastPage = await query.executeTakeFirst();
|
||||
|
||||
if (lastPage) {
|
||||
return generateJitteredKeyBetween(lastPage.position, null);
|
||||
@@ -198,20 +211,21 @@ export class ImportService {
|
||||
workspaceId: string,
|
||||
) {
|
||||
const file = await filePromise;
|
||||
const fileBuffer = await file.toBuffer();
|
||||
const fileExtension = path.extname(file.filename).toLowerCase();
|
||||
const fileName = sanitizeFileName(
|
||||
path.basename(file.filename, fileExtension),
|
||||
);
|
||||
const fileSize = fileBuffer.length;
|
||||
|
||||
const fileNameWithExt = fileName + fileExtension;
|
||||
|
||||
const fileTaskId = uuid7();
|
||||
const filePath = `${getFileTaskFolderPath(FileTaskType.Import, workspaceId)}/${fileTaskId}/${fileNameWithExt}`;
|
||||
|
||||
// upload file
|
||||
await this.storageService.upload(filePath, fileBuffer);
|
||||
const { stream, getBytesRead } = createByteCountingStream(file.file);
|
||||
|
||||
await this.storageService.upload(filePath, stream);
|
||||
|
||||
const fileSize = getBytesRead();
|
||||
|
||||
const fileTask = await this.db
|
||||
.insertInto('fileTasks')
|
||||
|
||||
@@ -20,9 +20,15 @@ export class LocalDriver implements StorageDriver {
|
||||
return join(this.config.storagePath, filePath);
|
||||
}
|
||||
|
||||
async upload(filePath: string, file: Buffer): Promise<void> {
|
||||
async upload(filePath: string, file: Buffer | Readable): Promise<void> {
|
||||
try {
|
||||
await fs.outputFile(this._fullPath(filePath), file);
|
||||
const fullPath = this._fullPath(filePath);
|
||||
if (file instanceof Buffer) {
|
||||
await fs.outputFile(fullPath, file);
|
||||
} else {
|
||||
await fs.mkdir(dirname(fullPath), { recursive: true });
|
||||
await pipeline(file, createWriteStream(fullPath));
|
||||
}
|
||||
} catch (err) {
|
||||
throw new Error(`Failed to upload file: ${(err as Error).message}`);
|
||||
}
|
||||
@@ -42,7 +48,7 @@ export class LocalDriver implements StorageDriver {
|
||||
try {
|
||||
const fromFullPath = this._fullPath(fromFilePath);
|
||||
const toFullPath = this._fullPath(toFilePath);
|
||||
|
||||
|
||||
if (await this.exists(fromFilePath)) {
|
||||
await fs.copy(fromFullPath, toFullPath);
|
||||
}
|
||||
|
||||
@@ -23,19 +23,21 @@ export class S3Driver implements StorageDriver {
|
||||
this.s3Client = new S3Client(config as any);
|
||||
}
|
||||
|
||||
async upload(filePath: string, file: Buffer): Promise<void> {
|
||||
async upload(filePath: string, file: Buffer | Readable): Promise<void> {
|
||||
try {
|
||||
const contentType = getMimeType(filePath);
|
||||
|
||||
const command = new PutObjectCommand({
|
||||
Bucket: this.config.bucket,
|
||||
Key: filePath,
|
||||
Body: file,
|
||||
ContentType: contentType,
|
||||
// ACL: "public-read",
|
||||
const upload = new Upload({
|
||||
client: this.s3Client,
|
||||
params: {
|
||||
Bucket: this.config.bucket,
|
||||
Key: filePath,
|
||||
Body: file,
|
||||
ContentType: contentType,
|
||||
},
|
||||
});
|
||||
|
||||
await this.s3Client.send(command);
|
||||
await upload.done();
|
||||
} catch (err) {
|
||||
throw new Error(`Failed to upload file: ${(err as Error).message}`);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Readable } from 'stream';
|
||||
|
||||
export interface StorageDriver {
|
||||
upload(filePath: string, file: Buffer): Promise<void>;
|
||||
upload(filePath: string, file: Buffer | Readable): Promise<void>;
|
||||
|
||||
uploadStream(filePath: string, file: Readable, options?: { recreateClient?: boolean }): Promise<void>;
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@ export class StorageService {
|
||||
private readonly logger = new Logger(StorageService.name);
|
||||
constructor(
|
||||
@Inject(STORAGE_DRIVER_TOKEN) private storageDriver: StorageDriver,
|
||||
) {}
|
||||
) { }
|
||||
|
||||
async upload(filePath: string, fileContent: Buffer | any) {
|
||||
async upload(filePath: string, fileContent: Buffer | Readable) {
|
||||
await this.storageDriver.upload(filePath, fileContent);
|
||||
this.logger.debug(`File uploaded successfully. Path: ${filePath}`);
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ import {
|
||||
NestFastifyApplication,
|
||||
} from '@nestjs/platform-fastify';
|
||||
import { Logger, NotFoundException, ValidationPipe } from '@nestjs/common';
|
||||
import { Logger as PinoLogger } from 'nestjs-pino';
|
||||
import { TransformHttpResponseInterceptor } from './common/interceptors/http-response.interceptor';
|
||||
import { WsRedisIoAdapter } from './ws/adapter/ws-redis.adapter';
|
||||
import { InternalLogFilter } from './common/logger/internal-log-filter';
|
||||
import fastifyMultipart from '@fastify/multipart';
|
||||
import fastifyCookie from '@fastify/cookie';
|
||||
|
||||
@@ -24,10 +24,12 @@ async function bootstrap() {
|
||||
}),
|
||||
{
|
||||
rawBody: true,
|
||||
logger: new InternalLogFilter(),
|
||||
bufferLogs: true,
|
||||
},
|
||||
);
|
||||
|
||||
app.useLogger(app.get(PinoLogger));
|
||||
|
||||
app.setGlobalPrefix('api', {
|
||||
exclude: ['robots.txt', 'share/:shareId/p/:pageSlug'],
|
||||
});
|
||||
@@ -99,9 +101,7 @@ async function bootstrap() {
|
||||
|
||||
const port = process.env.PORT || 3000;
|
||||
await app.listen(port, '0.0.0.0', () => {
|
||||
logger.log(
|
||||
`Listening on http://127.0.0.1:${port} / ${process.env.APP_URL}`,
|
||||
);
|
||||
logger.log(`Listening on http://127.0.0.1:${port} / ${process.env.APP_URL}`);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Generated
+146
-80
@@ -545,6 +545,9 @@ importers:
|
||||
kysely-migration-cli:
|
||||
specifier: ^0.4.2
|
||||
version: 0.4.2
|
||||
kysely-postgres-js:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0(kysely@0.28.2)(postgres@3.4.8)
|
||||
ldapts:
|
||||
specifier: ^7.4.0
|
||||
version: 7.4.0
|
||||
@@ -560,6 +563,9 @@ importers:
|
||||
nestjs-kysely:
|
||||
specifier: ^1.2.0
|
||||
version: 1.2.0(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)(kysely@0.28.2)(reflect-metadata@0.2.2)
|
||||
nestjs-pino:
|
||||
specifier: ^4.5.0
|
||||
version: 4.5.0(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(pino-http@11.0.0)(pino@10.1.0)(rxjs@7.8.2)
|
||||
nodemailer:
|
||||
specifier: ^7.0.12
|
||||
version: 7.0.12
|
||||
@@ -581,15 +587,21 @@ importers:
|
||||
pdfjs-dist:
|
||||
specifier: ^5.4.394
|
||||
version: 5.4.394
|
||||
pg:
|
||||
specifier: ^8.16.3
|
||||
version: 8.16.3
|
||||
pg-tsquery:
|
||||
specifier: ^8.4.2
|
||||
version: 8.4.2
|
||||
pgvector:
|
||||
specifier: ^0.2.1
|
||||
version: 0.2.1
|
||||
postgres:
|
||||
specifier: ^3.4.8
|
||||
version: 3.4.8
|
||||
pino-http:
|
||||
specifier: ^11.0.0
|
||||
version: 11.0.0
|
||||
pino-pretty:
|
||||
specifier: ^13.1.3
|
||||
version: 13.1.3
|
||||
postmark:
|
||||
specifier: ^4.0.5
|
||||
version: 4.0.5
|
||||
@@ -666,9 +678,6 @@ importers:
|
||||
'@types/passport-jwt':
|
||||
specifier: ^4.0.1
|
||||
version: 4.0.1
|
||||
'@types/pg':
|
||||
specifier: ^8.11.11
|
||||
version: 8.11.11
|
||||
'@types/supertest':
|
||||
specifier: ^6.0.2
|
||||
version: 6.0.2
|
||||
@@ -4764,9 +4773,6 @@ packages:
|
||||
'@types/passport@1.0.17':
|
||||
resolution: {integrity: sha512-aciLyx+wDwT2t2/kJGJR2AEeBz0nJU4WuRX04Wu9Dqc5lSUtwu0WERPHYsLhF9PtseiAMPBGNUOtFjxZ56prsg==}
|
||||
|
||||
'@types/pg@8.11.11':
|
||||
resolution: {integrity: sha512-kGT1qKM8wJQ5qlawUrEkXgvMSXoV213KfMGXcwfDwUIfUHXqXYXOfS1nE1LINRJVVVx5wCm70XnFlMHaIcQAfw==}
|
||||
|
||||
'@types/prop-types@15.7.11':
|
||||
resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==}
|
||||
|
||||
@@ -5587,6 +5593,9 @@ packages:
|
||||
resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
|
||||
engines: {node: '>=12.5.0'}
|
||||
|
||||
colorette@2.0.20:
|
||||
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
|
||||
|
||||
columnify@1.6.0:
|
||||
resolution: {integrity: sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
@@ -5947,6 +5956,9 @@ packages:
|
||||
date-fns@4.1.0:
|
||||
resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==}
|
||||
|
||||
dateformat@4.6.3:
|
||||
resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==}
|
||||
|
||||
dayjs@1.11.13:
|
||||
resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==}
|
||||
|
||||
@@ -6447,6 +6459,9 @@ packages:
|
||||
resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
fast-copy@4.0.2:
|
||||
resolution: {integrity: sha512-ybA6PDXIXOXivLJK/z9e+Otk7ve13I4ckBvGO5I2RRmBU1gMHLVDJYEuJYhGwez7YNlYji2M2DvVU+a9mSFDlw==}
|
||||
|
||||
fast-decode-uri-component@1.0.1:
|
||||
resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==}
|
||||
|
||||
@@ -6800,6 +6815,9 @@ packages:
|
||||
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
help-me@5.0.0:
|
||||
resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==}
|
||||
|
||||
hexoid@1.0.0:
|
||||
resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -7335,6 +7353,10 @@ packages:
|
||||
react:
|
||||
optional: true
|
||||
|
||||
joycon@3.1.1:
|
||||
resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
js-beautify@1.15.1:
|
||||
resolution: {integrity: sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==}
|
||||
engines: {node: '>=14'}
|
||||
@@ -7504,6 +7526,16 @@ packages:
|
||||
resolution: {integrity: sha512-904MSUdzkdxl+k3C67ogvP6ogPOEr0D6ZZDtxAmDeIHEJxZAA+eC+TLAcJt3HQABTPetwsW3pj6y1MPmaveQUg==}
|
||||
hasBin: true
|
||||
|
||||
kysely-postgres-js@3.0.0:
|
||||
resolution: {integrity: sha512-o2t/xNSYJQDW6rVGGFPXKmZ0BEz2dGn66c2B+cO/k9ZNcU2qPWPycQPQ+B+P2MBXbKYq0xV9BZmFIvkUrmFWAQ==}
|
||||
engines: {bun: '>=1.2', node: '>=20'}
|
||||
peerDependencies:
|
||||
kysely: '>= 0.24.0 < 1'
|
||||
postgres: ^3.4.0
|
||||
peerDependenciesMeta:
|
||||
postgres:
|
||||
optional: true
|
||||
|
||||
kysely@0.28.2:
|
||||
resolution: {integrity: sha512-4YAVLoF0Sf0UTqlhgQMFU9iQECdah7n+13ANkiuVfRvlK+uI0Etbgd7bVP36dKlG+NXWbhGua8vnGt+sdhvT7A==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
@@ -7994,6 +8026,15 @@ packages:
|
||||
kysely: 0.x
|
||||
reflect-metadata: ^0.1.13 || ^0.2.2
|
||||
|
||||
nestjs-pino@4.5.0:
|
||||
resolution: {integrity: sha512-e54ChJMACSGF8gPYaHsuD07RW7l/OVoV6aI8Hqhpp0ZQ4WA8QY3eewL42JX7Z1U6rV7byNU7bGBV9l6d9V6PDQ==}
|
||||
engines: {node: '>= 14'}
|
||||
peerDependencies:
|
||||
'@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0
|
||||
pino: ^7.5.0 || ^8.0.0 || ^9.0.0 || ^10.0.0
|
||||
pino-http: ^6.4.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0
|
||||
rxjs: ^7.1.0
|
||||
|
||||
next@14.2.10:
|
||||
resolution: {integrity: sha512-sDDExXnh33cY3RkS9JuFEKaS4HmlWmDKP1VJioucCG6z5KuA008DPsDZOzi8UfqEk3Ii+2NCQSJrfbEWtZZfww==}
|
||||
engines: {node: '>=18.17.0'}
|
||||
@@ -8133,9 +8174,6 @@ packages:
|
||||
resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
obuf@1.1.2:
|
||||
resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==}
|
||||
|
||||
oidc-token-hash@5.0.3:
|
||||
resolution: {integrity: sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==}
|
||||
engines: {node: ^10.13.0 || >=12.0.0}
|
||||
@@ -8360,10 +8398,6 @@ packages:
|
||||
resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
|
||||
pg-numeric@1.0.2:
|
||||
resolution: {integrity: sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
pg-pool@3.10.1:
|
||||
resolution: {integrity: sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==}
|
||||
peerDependencies:
|
||||
@@ -8372,9 +8406,6 @@ packages:
|
||||
pg-protocol@1.10.3:
|
||||
resolution: {integrity: sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==}
|
||||
|
||||
pg-protocol@1.7.0:
|
||||
resolution: {integrity: sha512-hTK/mE36i8fDDhgDFjy6xNOG+LCorxLG3WO17tku+ij6sVHXh1jQUJ8hYAnRhNla4QVD2H8er/FOjc/+EgC6yQ==}
|
||||
|
||||
pg-tsquery@8.4.2:
|
||||
resolution: {integrity: sha512-waJSlBIKE+shDhuDpuQglTH6dG5zakDhnrnxu8XB8V5c7yoDSuy4pOxY6t2dyoxTjaKMcMmlByJN7n9jx9eqMA==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -8383,10 +8414,6 @@ packages:
|
||||
resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
pg-types@4.0.2:
|
||||
resolution: {integrity: sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
pg@8.16.3:
|
||||
resolution: {integrity: sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==}
|
||||
engines: {node: '>= 16.0.0'}
|
||||
@@ -8434,6 +8461,16 @@ packages:
|
||||
pino-abstract-transport@2.0.0:
|
||||
resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==}
|
||||
|
||||
pino-abstract-transport@3.0.0:
|
||||
resolution: {integrity: sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg==}
|
||||
|
||||
pino-http@11.0.0:
|
||||
resolution: {integrity: sha512-wqg5XIAGRRIWtTk8qPGxkbrfiwEWz1lgedVLvhLALudKXvg1/L2lTFgTGPJ4Z2e3qcRmxoFxDuSdMdMGNM6I1g==}
|
||||
|
||||
pino-pretty@13.1.3:
|
||||
resolution: {integrity: sha512-ttXRkkOz6WWC95KeY9+xxWL6AtImwbyMHrL1mSwqwW9u+vLp/WIElvHvCSDg0xO/Dzrggz1zv3rN5ovTRVowKg==}
|
||||
hasBin: true
|
||||
|
||||
pino-std-serializers@7.0.0:
|
||||
resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==}
|
||||
|
||||
@@ -8534,37 +8571,22 @@ packages:
|
||||
resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
postgres-array@3.0.2:
|
||||
resolution: {integrity: sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
postgres-bytea@1.0.0:
|
||||
resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
postgres-bytea@3.0.0:
|
||||
resolution: {integrity: sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
postgres-date@1.0.7:
|
||||
resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
postgres-date@2.1.0:
|
||||
resolution: {integrity: sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
postgres-interval@1.2.0:
|
||||
resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
postgres-interval@3.0.0:
|
||||
resolution: {integrity: sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==}
|
||||
postgres@3.4.8:
|
||||
resolution: {integrity: sha512-d+JFcLM17njZaOLkv6SCev7uoLaBtfK86vMUXhW1Z4glPWh4jozno9APvW/XKFJ3CCxVoC7OL38BqRydtu5nGg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
postgres-range@1.1.4:
|
||||
resolution: {integrity: sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==}
|
||||
|
||||
posthog-js@1.255.1:
|
||||
resolution: {integrity: sha512-KMh0o9MhORhEZVjXpktXB5rJ8PfDk+poqBoTSoLzWgNjhJf6D8jcyB9jUMA6vVPfn4YeepVX5NuclDRqOwr5Mw==}
|
||||
peerDependencies:
|
||||
@@ -8691,6 +8713,9 @@ packages:
|
||||
prr@1.0.1:
|
||||
resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
|
||||
|
||||
pump@3.0.3:
|
||||
resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==}
|
||||
|
||||
punycode.js@2.3.1:
|
||||
resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==}
|
||||
engines: {node: '>=6'}
|
||||
@@ -9368,6 +9393,10 @@ packages:
|
||||
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
strip-json-comments@5.0.3:
|
||||
resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==}
|
||||
engines: {node: '>=14.16'}
|
||||
|
||||
stripe@17.5.0:
|
||||
resolution: {integrity: sha512-kcyeAkDFjGsVl17FqnG7q/+xIjt0ZjOo9Dm+q8deAvs2Xe4iAHrhxyoP4etUVFc+/LZJANjIPVR+ZOnt9hr/Ug==}
|
||||
engines: {node: '>=12.*'}
|
||||
@@ -15197,12 +15226,6 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/express': 4.17.23
|
||||
|
||||
'@types/pg@8.11.11':
|
||||
dependencies:
|
||||
'@types/node': 22.19.1
|
||||
pg-protocol: 1.7.0
|
||||
pg-types: 4.0.2
|
||||
|
||||
'@types/prop-types@15.7.11': {}
|
||||
|
||||
'@types/qrcode@1.5.5':
|
||||
@@ -16229,6 +16252,8 @@ snapshots:
|
||||
color-convert: 2.0.1
|
||||
color-string: 1.9.1
|
||||
|
||||
colorette@2.0.20: {}
|
||||
|
||||
columnify@1.6.0:
|
||||
dependencies:
|
||||
strip-ansi: 6.0.1
|
||||
@@ -16636,6 +16661,8 @@ snapshots:
|
||||
|
||||
date-fns@4.1.0: {}
|
||||
|
||||
dateformat@4.6.3: {}
|
||||
|
||||
dayjs@1.11.13: {}
|
||||
|
||||
dayjs@1.11.19: {}
|
||||
@@ -17268,6 +17295,8 @@ snapshots:
|
||||
iconv-lite: 0.4.24
|
||||
tmp: 0.0.33
|
||||
|
||||
fast-copy@4.0.2: {}
|
||||
|
||||
fast-decode-uri-component@1.0.1: {}
|
||||
|
||||
fast-deep-equal@2.0.1: {}
|
||||
@@ -17654,6 +17683,8 @@ snapshots:
|
||||
dependencies:
|
||||
function-bind: 1.1.2
|
||||
|
||||
help-me@5.0.0: {}
|
||||
|
||||
hexoid@1.0.0: {}
|
||||
|
||||
highlight.js@11.11.1: {}
|
||||
@@ -18408,6 +18439,8 @@ snapshots:
|
||||
'@types/react': 18.3.12
|
||||
react: 18.3.1
|
||||
|
||||
joycon@3.1.1: {}
|
||||
|
||||
js-beautify@1.15.1:
|
||||
dependencies:
|
||||
config-chain: 1.1.13
|
||||
@@ -18579,6 +18612,12 @@ snapshots:
|
||||
'@commander-js/extra-typings': 11.1.0(commander@11.1.0)
|
||||
commander: 11.1.0
|
||||
|
||||
kysely-postgres-js@3.0.0(kysely@0.28.2)(postgres@3.4.8):
|
||||
dependencies:
|
||||
kysely: 0.28.2
|
||||
optionalDependencies:
|
||||
postgres: 3.4.8
|
||||
|
||||
kysely@0.28.2: {}
|
||||
|
||||
langium@3.3.1:
|
||||
@@ -19159,6 +19198,13 @@ snapshots:
|
||||
kysely: 0.28.2
|
||||
reflect-metadata: 0.2.2
|
||||
|
||||
nestjs-pino@4.5.0(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(pino-http@11.0.0)(pino@10.1.0)(rxjs@7.8.2):
|
||||
dependencies:
|
||||
'@nestjs/common': 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||
pino: 10.1.0
|
||||
pino-http: 11.0.0
|
||||
rxjs: 7.8.2
|
||||
|
||||
next@14.2.10(@babel/core@7.24.5)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.51.0):
|
||||
dependencies:
|
||||
'@next/env': 14.2.10
|
||||
@@ -19327,8 +19373,6 @@ snapshots:
|
||||
define-properties: 1.2.1
|
||||
es-object-atoms: 1.0.0
|
||||
|
||||
obuf@1.1.2: {}
|
||||
|
||||
oidc-token-hash@5.0.3: {}
|
||||
|
||||
ollama@0.6.3:
|
||||
@@ -19553,19 +19597,19 @@ snapshots:
|
||||
pg-cloudflare@1.2.7:
|
||||
optional: true
|
||||
|
||||
pg-connection-string@2.9.1: {}
|
||||
pg-connection-string@2.9.1:
|
||||
optional: true
|
||||
|
||||
pg-int8@1.0.1: {}
|
||||
|
||||
pg-numeric@1.0.2: {}
|
||||
pg-int8@1.0.1:
|
||||
optional: true
|
||||
|
||||
pg-pool@3.10.1(pg@8.16.3):
|
||||
dependencies:
|
||||
pg: 8.16.3
|
||||
optional: true
|
||||
|
||||
pg-protocol@1.10.3: {}
|
||||
|
||||
pg-protocol@1.7.0: {}
|
||||
pg-protocol@1.10.3:
|
||||
optional: true
|
||||
|
||||
pg-tsquery@8.4.2: {}
|
||||
|
||||
@@ -19576,16 +19620,7 @@ snapshots:
|
||||
postgres-bytea: 1.0.0
|
||||
postgres-date: 1.0.7
|
||||
postgres-interval: 1.2.0
|
||||
|
||||
pg-types@4.0.2:
|
||||
dependencies:
|
||||
pg-int8: 1.0.1
|
||||
pg-numeric: 1.0.2
|
||||
postgres-array: 3.0.2
|
||||
postgres-bytea: 3.0.0
|
||||
postgres-date: 2.1.0
|
||||
postgres-interval: 3.0.0
|
||||
postgres-range: 1.1.4
|
||||
optional: true
|
||||
|
||||
pg@8.16.3:
|
||||
dependencies:
|
||||
@@ -19596,10 +19631,12 @@ snapshots:
|
||||
pgpass: 1.0.5
|
||||
optionalDependencies:
|
||||
pg-cloudflare: 1.2.7
|
||||
optional: true
|
||||
|
||||
pgpass@1.0.5:
|
||||
dependencies:
|
||||
split2: 4.2.0
|
||||
optional: true
|
||||
|
||||
pgvector@0.2.1: {}
|
||||
|
||||
@@ -19630,6 +19667,33 @@ snapshots:
|
||||
dependencies:
|
||||
split2: 4.2.0
|
||||
|
||||
pino-abstract-transport@3.0.0:
|
||||
dependencies:
|
||||
split2: 4.2.0
|
||||
|
||||
pino-http@11.0.0:
|
||||
dependencies:
|
||||
get-caller-file: 2.0.5
|
||||
pino: 10.1.0
|
||||
pino-std-serializers: 7.0.0
|
||||
process-warning: 5.0.0
|
||||
|
||||
pino-pretty@13.1.3:
|
||||
dependencies:
|
||||
colorette: 2.0.20
|
||||
dateformat: 4.6.3
|
||||
fast-copy: 4.0.2
|
||||
fast-safe-stringify: 2.1.1
|
||||
help-me: 5.0.0
|
||||
joycon: 3.1.1
|
||||
minimist: 1.2.8
|
||||
on-exit-leak-free: 2.1.2
|
||||
pino-abstract-transport: 3.0.0
|
||||
pump: 3.0.3
|
||||
secure-json-parse: 4.0.0
|
||||
sonic-boom: 4.0.1
|
||||
strip-json-comments: 5.0.3
|
||||
|
||||
pino-std-serializers@7.0.0: {}
|
||||
|
||||
pino@10.1.0:
|
||||
@@ -19741,27 +19805,21 @@ snapshots:
|
||||
picocolors: 1.1.1
|
||||
source-map-js: 1.2.1
|
||||
|
||||
postgres-array@2.0.0: {}
|
||||
postgres-array@2.0.0:
|
||||
optional: true
|
||||
|
||||
postgres-array@3.0.2: {}
|
||||
postgres-bytea@1.0.0:
|
||||
optional: true
|
||||
|
||||
postgres-bytea@1.0.0: {}
|
||||
|
||||
postgres-bytea@3.0.0:
|
||||
dependencies:
|
||||
obuf: 1.1.2
|
||||
|
||||
postgres-date@1.0.7: {}
|
||||
|
||||
postgres-date@2.1.0: {}
|
||||
postgres-date@1.0.7:
|
||||
optional: true
|
||||
|
||||
postgres-interval@1.2.0:
|
||||
dependencies:
|
||||
xtend: 4.0.2
|
||||
optional: true
|
||||
|
||||
postgres-interval@3.0.0: {}
|
||||
|
||||
postgres-range@1.1.4: {}
|
||||
postgres@3.4.8: {}
|
||||
|
||||
posthog-js@1.255.1:
|
||||
dependencies:
|
||||
@@ -19921,6 +19979,11 @@ snapshots:
|
||||
prr@1.0.1:
|
||||
optional: true
|
||||
|
||||
pump@3.0.3:
|
||||
dependencies:
|
||||
end-of-stream: 1.4.4
|
||||
once: 1.4.0
|
||||
|
||||
punycode.js@2.3.1: {}
|
||||
|
||||
punycode@2.3.1: {}
|
||||
@@ -20705,6 +20768,8 @@ snapshots:
|
||||
|
||||
strip-json-comments@3.1.1: {}
|
||||
|
||||
strip-json-comments@5.0.3: {}
|
||||
|
||||
stripe@17.5.0:
|
||||
dependencies:
|
||||
'@types/node': 22.19.1
|
||||
@@ -21441,7 +21506,8 @@ snapshots:
|
||||
|
||||
xpath@0.0.34: {}
|
||||
|
||||
xtend@4.0.2: {}
|
||||
xtend@4.0.2:
|
||||
optional: true
|
||||
|
||||
y-indexeddb@9.0.12(yjs@13.6.29):
|
||||
dependencies:
|
||||
|
||||
Reference in New Issue
Block a user