mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-13 00:03:27 +10:00
fix(i18n): delete local translations
This commit is contained in:
@ -57,6 +57,10 @@ REDIS_URL=redis://default:password@localhost:6379
|
|||||||
# Sentry (for error reporting, Optional)
|
# Sentry (for error reporting, Optional)
|
||||||
# SENTRY_DSN=
|
# SENTRY_DSN=
|
||||||
|
|
||||||
|
# Crowdin (Optional)
|
||||||
|
CROWDIN_DISTRIBUTION_HASH=
|
||||||
|
CROWDIN_PERSONAL_TOKEN=
|
||||||
|
|
||||||
# GitHub (OAuth, Optional)
|
# GitHub (OAuth, Optional)
|
||||||
GITHUB_CLIENT_ID=
|
GITHUB_CLIENT_ID=
|
||||||
GITHUB_CLIENT_SECRET=
|
GITHUB_CLIENT_SECRET=
|
||||||
|
|||||||
14
.github/workflows/update-translations.yml
vendored
14
.github/workflows/update-translations.yml
vendored
@ -10,20 +10,16 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout Repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4.1.1
|
||||||
|
|
||||||
- name: crowdin action
|
- name: Sync Sources with Crowdin
|
||||||
uses: crowdin/github-action@v1
|
uses: crowdin/github-action@v1
|
||||||
with:
|
with:
|
||||||
upload_sources: true
|
upload_sources: true
|
||||||
create_pull_request: true
|
create_pull_request: false
|
||||||
upload_translations: false
|
upload_translations: false
|
||||||
download_translations: true
|
download_translations: false
|
||||||
localization_branch_name: l10n
|
|
||||||
pull_request_base_branch_name: "v4"
|
|
||||||
pull_request_title: "New Translations"
|
|
||||||
pull_request_body: "There have been new translations added to the project. Please review and merge the changes made on Crowdin to help keep them in sync."
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -48,4 +48,4 @@ libs/prisma
|
|||||||
|
|
||||||
# Lingui Compiled Messages
|
# Lingui Compiled Messages
|
||||||
apps/client/src/locales/_build/
|
apps/client/src/locales/_build/
|
||||||
apps/client/src/locales/**/*.js
|
apps/client/src/locales
|
||||||
@ -1,6 +1,8 @@
|
|||||||
import { i18n } from "@lingui/core";
|
import { i18n } from "@lingui/core";
|
||||||
import { t } from "@lingui/macro";
|
import { t } from "@lingui/macro";
|
||||||
|
|
||||||
|
import { axios } from "./axios";
|
||||||
|
|
||||||
type Locale = "en-US" | "de-DE" | "zu-ZA";
|
type Locale = "en-US" | "de-DE" | "zu-ZA";
|
||||||
|
|
||||||
export const defaultLocale = "en-US";
|
export const defaultLocale = "en-US";
|
||||||
@ -20,7 +22,8 @@ export const getLocales = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export async function dynamicActivate(locale: string) {
|
export async function dynamicActivate(locale: string) {
|
||||||
const { messages } = await import(`../locales/${locale}/messages.po`);
|
const response = await axios(`translation/${locale}`);
|
||||||
|
const messages = await response.data;
|
||||||
|
|
||||||
i18n.load(locale, messages);
|
i18n.load(locale, messages);
|
||||||
i18n.activate(locale);
|
i18n.activate(locale);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -14,6 +14,7 @@ import { MailModule } from "./mail/mail.module";
|
|||||||
import { PrinterModule } from "./printer/printer.module";
|
import { PrinterModule } from "./printer/printer.module";
|
||||||
import { ResumeModule } from "./resume/resume.module";
|
import { ResumeModule } from "./resume/resume.module";
|
||||||
import { StorageModule } from "./storage/storage.module";
|
import { StorageModule } from "./storage/storage.module";
|
||||||
|
import { TranslationModule } from "./translation/translation.module";
|
||||||
import { UserModule } from "./user/user.module";
|
import { UserModule } from "./user/user.module";
|
||||||
import { UtilsModule } from "./utils/utils.module";
|
import { UtilsModule } from "./utils/utils.module";
|
||||||
|
|
||||||
@ -34,6 +35,7 @@ import { UtilsModule } from "./utils/utils.module";
|
|||||||
ResumeModule,
|
ResumeModule,
|
||||||
StorageModule,
|
StorageModule,
|
||||||
PrinterModule,
|
PrinterModule,
|
||||||
|
TranslationModule,
|
||||||
|
|
||||||
// Static Assets
|
// Static Assets
|
||||||
ServeStaticModule.forRoot({
|
ServeStaticModule.forRoot({
|
||||||
|
|||||||
23
apps/server/src/cache/cache.module.ts
vendored
23
apps/server/src/cache/cache.module.ts
vendored
@ -1,8 +1,6 @@
|
|||||||
import { CacheModule as NestCacheModule } from "@nestjs/cache-manager";
|
import { Module } from "@nestjs/common";
|
||||||
import { Logger, Module } from "@nestjs/common";
|
|
||||||
import { ConfigService } from "@nestjs/config";
|
import { ConfigService } from "@nestjs/config";
|
||||||
import { RedisModule } from "@songkeys/nestjs-redis";
|
import { RedisModule } from "@songkeys/nestjs-redis";
|
||||||
import { redisStore } from "cache-manager-redis-yet";
|
|
||||||
|
|
||||||
import { Config } from "../config/schema";
|
import { Config } from "../config/schema";
|
||||||
|
|
||||||
@ -14,25 +12,6 @@ import { Config } from "../config/schema";
|
|||||||
config: { url: configService.getOrThrow("REDIS_URL") },
|
config: { url: configService.getOrThrow("REDIS_URL") },
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
NestCacheModule.registerAsync({
|
|
||||||
isGlobal: true,
|
|
||||||
|
|
||||||
inject: [ConfigService],
|
|
||||||
useFactory: async (configService: ConfigService<Config>) => {
|
|
||||||
const url = configService.get("REDIS_URL");
|
|
||||||
|
|
||||||
if (!url) {
|
|
||||||
Logger.warn(
|
|
||||||
"`REDIS_URL` was not set, using in-memory cache instead. This is not suitable for production.",
|
|
||||||
"CacheModule",
|
|
||||||
);
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return { store: await redisStore({ url }) };
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class CacheModule {}
|
export class CacheModule {}
|
||||||
|
|||||||
@ -42,6 +42,9 @@ export const configSchema = z.object({
|
|||||||
// Sentry
|
// Sentry
|
||||||
SENTRY_DSN: z.string().url().startsWith("https://").optional(),
|
SENTRY_DSN: z.string().url().startsWith("https://").optional(),
|
||||||
|
|
||||||
|
// Crowdin (Optional)
|
||||||
|
CROWDIN_DISTRIBUTION_HASH: z.string().optional(),
|
||||||
|
|
||||||
// GitHub (OAuth)
|
// GitHub (OAuth)
|
||||||
GITHUB_CLIENT_ID: z.string().optional(),
|
GITHUB_CLIENT_ID: z.string().optional(),
|
||||||
GITHUB_CLIENT_SECRET: z.string().optional(),
|
GITHUB_CLIENT_SECRET: z.string().optional(),
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import { CacheInterceptor, CacheKey, CacheTTL } from "@nestjs/cache-manager";
|
import { Controller, Get, NotFoundException } from "@nestjs/common";
|
||||||
import { Controller, Get, NotFoundException, UseInterceptors } from "@nestjs/common";
|
|
||||||
import { ApiTags } from "@nestjs/swagger";
|
import { ApiTags } from "@nestjs/swagger";
|
||||||
import { HealthCheck, HealthCheckService } from "@nestjs/terminus";
|
import { HealthCheck, HealthCheckService } from "@nestjs/terminus";
|
||||||
import { RedisService } from "@songkeys/nestjs-redis";
|
import { RedisService } from "@songkeys/nestjs-redis";
|
||||||
import { RedisHealthIndicator } from "@songkeys/nestjs-redis-health";
|
import { RedisHealthIndicator } from "@songkeys/nestjs-redis-health";
|
||||||
|
|
||||||
import { configSchema } from "../config/schema";
|
import { configSchema } from "../config/schema";
|
||||||
|
import { UtilsService } from "../utils/utils.service";
|
||||||
import { BrowserHealthIndicator } from "./browser.health";
|
import { BrowserHealthIndicator } from "./browser.health";
|
||||||
import { DatabaseHealthIndicator } from "./database.health";
|
import { DatabaseHealthIndicator } from "./database.health";
|
||||||
import { StorageHealthIndicator } from "./storage.health";
|
import { StorageHealthIndicator } from "./storage.health";
|
||||||
@ -20,14 +20,10 @@ export class HealthController {
|
|||||||
private readonly storage: StorageHealthIndicator,
|
private readonly storage: StorageHealthIndicator,
|
||||||
private readonly redisService: RedisService,
|
private readonly redisService: RedisService,
|
||||||
private readonly redis: RedisHealthIndicator,
|
private readonly redis: RedisHealthIndicator,
|
||||||
|
private readonly utils: UtilsService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Get()
|
private run() {
|
||||||
@HealthCheck()
|
|
||||||
@UseInterceptors(CacheInterceptor)
|
|
||||||
@CacheKey("health:check")
|
|
||||||
@CacheTTL(30000) // 30 seconds
|
|
||||||
check() {
|
|
||||||
return this.health.check([
|
return this.health.check([
|
||||||
() => this.database.isHealthy(),
|
() => this.database.isHealthy(),
|
||||||
() => this.storage.isHealthy(),
|
() => this.storage.isHealthy(),
|
||||||
@ -42,6 +38,12 @@ export class HealthController {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get()
|
||||||
|
@HealthCheck()
|
||||||
|
check() {
|
||||||
|
return this.utils.getCachedOrSet(`health:check`, () => this.run(), 1000 * 30); // 30 seconds
|
||||||
|
}
|
||||||
|
|
||||||
@Get("environment")
|
@Get("environment")
|
||||||
environment() {
|
environment() {
|
||||||
if (process.env.NODE_ENV === "production") throw new NotFoundException();
|
if (process.env.NODE_ENV === "production") throw new NotFoundException();
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { CacheInterceptor, CacheKey } from "@nestjs/cache-manager";
|
|
||||||
import {
|
import {
|
||||||
BadRequestException,
|
BadRequestException,
|
||||||
Body,
|
Body,
|
||||||
@ -11,7 +10,6 @@ import {
|
|||||||
Patch,
|
Patch,
|
||||||
Post,
|
Post,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
UseInterceptors,
|
|
||||||
} from "@nestjs/common";
|
} from "@nestjs/common";
|
||||||
import { ApiTags } from "@nestjs/swagger";
|
import { ApiTags } from "@nestjs/swagger";
|
||||||
import { User as UserEntity } from "@prisma/client";
|
import { User as UserEntity } from "@prisma/client";
|
||||||
@ -25,6 +23,7 @@ import { User } from "@/server/user/decorators/user.decorator";
|
|||||||
import { OptionalGuard } from "../auth/guards/optional.guard";
|
import { OptionalGuard } from "../auth/guards/optional.guard";
|
||||||
import { TwoFactorGuard } from "../auth/guards/two-factor.guard";
|
import { TwoFactorGuard } from "../auth/guards/two-factor.guard";
|
||||||
import { ErrorMessage } from "../constants/error-message";
|
import { ErrorMessage } from "../constants/error-message";
|
||||||
|
import { UtilsService } from "../utils/utils.service";
|
||||||
import { Resume } from "./decorators/resume.decorator";
|
import { Resume } from "./decorators/resume.decorator";
|
||||||
import { ResumeGuard } from "./guards/resume.guard";
|
import { ResumeGuard } from "./guards/resume.guard";
|
||||||
import { ResumeService } from "./resume.service";
|
import { ResumeService } from "./resume.service";
|
||||||
@ -32,13 +31,18 @@ import { ResumeService } from "./resume.service";
|
|||||||
@ApiTags("Resume")
|
@ApiTags("Resume")
|
||||||
@Controller("resume")
|
@Controller("resume")
|
||||||
export class ResumeController {
|
export class ResumeController {
|
||||||
constructor(private readonly resumeService: ResumeService) {}
|
constructor(
|
||||||
|
private readonly resumeService: ResumeService,
|
||||||
|
private readonly utils: UtilsService,
|
||||||
|
) {}
|
||||||
|
|
||||||
@Get("schema")
|
@Get("schema")
|
||||||
@UseInterceptors(CacheInterceptor)
|
getSchema() {
|
||||||
@CacheKey("resume:schema")
|
return this.utils.getCachedOrSet(
|
||||||
async getSchema() {
|
`resume:schema`,
|
||||||
return zodToJsonSchema(resumeDataSchema);
|
() => zodToJsonSchema(resumeDataSchema),
|
||||||
|
1000 * 60 * 60 * 24, // 24 hours
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
import { CACHE_MANAGER } from "@nestjs/cache-manager";
|
import { BadRequestException, Injectable, Logger } from "@nestjs/common";
|
||||||
import { BadRequestException, Inject, Injectable, Logger } from "@nestjs/common";
|
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
import { CreateResumeDto, ImportResumeDto, ResumeDto, UpdateResumeDto } from "@reactive-resume/dto";
|
import { CreateResumeDto, ImportResumeDto, ResumeDto, UpdateResumeDto } from "@reactive-resume/dto";
|
||||||
import { defaultResumeData, ResumeData } from "@reactive-resume/schema";
|
import { defaultResumeData, ResumeData } from "@reactive-resume/schema";
|
||||||
import type { DeepPartial } from "@reactive-resume/utils";
|
import type { DeepPartial } from "@reactive-resume/utils";
|
||||||
import { generateRandomName, kebabCase } from "@reactive-resume/utils";
|
import { generateRandomName, kebabCase } from "@reactive-resume/utils";
|
||||||
import { RedisService } from "@songkeys/nestjs-redis";
|
import { RedisService } from "@songkeys/nestjs-redis";
|
||||||
import { Cache } from "cache-manager";
|
|
||||||
import deepmerge from "deepmerge";
|
import deepmerge from "deepmerge";
|
||||||
import Redis from "ioredis";
|
import Redis from "ioredis";
|
||||||
import { PrismaService } from "nestjs-prisma";
|
import { PrismaService } from "nestjs-prisma";
|
||||||
@ -28,7 +26,6 @@ export class ResumeService {
|
|||||||
private readonly storageService: StorageService,
|
private readonly storageService: StorageService,
|
||||||
private readonly redisService: RedisService,
|
private readonly redisService: RedisService,
|
||||||
private readonly utils: UtilsService,
|
private readonly utils: UtilsService,
|
||||||
@Inject(CACHE_MANAGER) private readonly cache: Cache,
|
|
||||||
) {
|
) {
|
||||||
this.redis = this.redisService.getClient();
|
this.redis = this.redisService.getClient();
|
||||||
}
|
}
|
||||||
@ -54,8 +51,8 @@ export class ResumeService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.cache.del(`user:${userId}:resumes`),
|
this.redis.del(`user:${userId}:resumes`),
|
||||||
this.cache.set(`user:${userId}:resume:${resume.id}`, resume),
|
this.redis.set(`user:${userId}:resume:${resume.id}`, JSON.stringify(resume)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return resume;
|
return resume;
|
||||||
@ -75,8 +72,8 @@ export class ResumeService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.cache.del(`user:${userId}:resumes`),
|
this.redis.del(`user:${userId}:resumes`),
|
||||||
this.cache.set(`user:${userId}:resume:${resume.id}`, resume),
|
this.redis.set(`user:${userId}:resume:${resume.id}`, JSON.stringify(resume)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return resume;
|
return resume;
|
||||||
@ -142,10 +139,10 @@ export class ResumeService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.cache.set(`user:${userId}:resume:${id}`, resume),
|
this.redis.set(`user:${userId}:resume:${id}`, JSON.stringify(resume)),
|
||||||
this.cache.del(`user:${userId}:resumes`),
|
this.redis.del(`user:${userId}:resumes`),
|
||||||
this.cache.del(`user:${userId}:storage:resumes:${id}`),
|
this.redis.del(`user:${userId}:storage:resumes:${id}`),
|
||||||
this.cache.del(`user:${userId}:storage:previews:${id}`),
|
this.redis.del(`user:${userId}:storage:previews:${id}`),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return resume;
|
return resume;
|
||||||
@ -163,8 +160,8 @@ export class ResumeService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.cache.set(`user:${userId}:resume:${id}`, resume),
|
this.redis.set(`user:${userId}:resume:${id}`, JSON.stringify(resume)),
|
||||||
this.cache.del(`user:${userId}:resumes`),
|
this.redis.del(`user:${userId}:resumes`),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return resume;
|
return resume;
|
||||||
@ -173,8 +170,8 @@ export class ResumeService {
|
|||||||
async remove(userId: string, id: string) {
|
async remove(userId: string, id: string) {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
// Remove cached keys
|
// Remove cached keys
|
||||||
this.cache.del(`user:${userId}:resumes`),
|
this.redis.del(`user:${userId}:resumes`),
|
||||||
this.cache.del(`user:${userId}:resume:${id}`),
|
this.redis.del(`user:${userId}:resume:${id}`),
|
||||||
|
|
||||||
// Remove files in storage, and their cached keys
|
// Remove files in storage, and their cached keys
|
||||||
this.storageService.deleteObject(userId, "resumes", id),
|
this.storageService.deleteObject(userId, "resumes", id),
|
||||||
|
|||||||
@ -1,14 +1,8 @@
|
|||||||
import { CACHE_MANAGER } from "@nestjs/cache-manager";
|
import { Injectable, InternalServerErrorException, Logger, OnModuleInit } from "@nestjs/common";
|
||||||
import {
|
|
||||||
Inject,
|
|
||||||
Injectable,
|
|
||||||
InternalServerErrorException,
|
|
||||||
Logger,
|
|
||||||
OnModuleInit,
|
|
||||||
} from "@nestjs/common";
|
|
||||||
import { ConfigService } from "@nestjs/config";
|
import { ConfigService } from "@nestjs/config";
|
||||||
import { createId } from "@paralleldrive/cuid2";
|
import { createId } from "@paralleldrive/cuid2";
|
||||||
import { Cache } from "cache-manager";
|
import { RedisService } from "@songkeys/nestjs-redis";
|
||||||
|
import { Redis } from "ioredis";
|
||||||
import { Client } from "minio";
|
import { Client } from "minio";
|
||||||
import { MinioService } from "nestjs-minio-client";
|
import { MinioService } from "nestjs-minio-client";
|
||||||
import sharp from "sharp";
|
import sharp from "sharp";
|
||||||
@ -44,6 +38,7 @@ const PUBLIC_ACCESS_POLICY = {
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class StorageService implements OnModuleInit {
|
export class StorageService implements OnModuleInit {
|
||||||
|
private readonly redis: Redis;
|
||||||
private readonly logger = new Logger(StorageService.name);
|
private readonly logger = new Logger(StorageService.name);
|
||||||
|
|
||||||
private client: Client;
|
private client: Client;
|
||||||
@ -52,8 +47,10 @@ export class StorageService implements OnModuleInit {
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly configService: ConfigService<Config>,
|
private readonly configService: ConfigService<Config>,
|
||||||
private readonly minioService: MinioService,
|
private readonly minioService: MinioService,
|
||||||
@Inject(CACHE_MANAGER) private readonly cache: Cache,
|
private readonly redisService: RedisService,
|
||||||
) {}
|
) {
|
||||||
|
this.redis = this.redisService.getClient();
|
||||||
|
}
|
||||||
|
|
||||||
async onModuleInit() {
|
async onModuleInit() {
|
||||||
this.client = this.minioService.client;
|
this.client = this.minioService.client;
|
||||||
@ -125,7 +122,7 @@ export class StorageService implements OnModuleInit {
|
|||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.client.putObject(this.bucketName, filepath, buffer, metadata),
|
this.client.putObject(this.bucketName, filepath, buffer, metadata),
|
||||||
this.cache.set(`user:${userId}:storage:${type}:${filename}`, url),
|
this.redis.set(`user:${userId}:storage:${type}:${filename}`, url),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
@ -140,7 +137,7 @@ export class StorageService implements OnModuleInit {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
this.cache.del(`user:${userId}:storage:${type}:${filename}`),
|
this.redis.del(`user:${userId}:storage:${type}:${filename}`),
|
||||||
this.client.removeObject(this.bucketName, path),
|
this.client.removeObject(this.bucketName, path),
|
||||||
]);
|
]);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
35
apps/server/src/translation/translation.controller.ts
Normal file
35
apps/server/src/translation/translation.controller.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { HttpService } from "@nestjs/axios";
|
||||||
|
import { Controller, Get, Header, Param } from "@nestjs/common";
|
||||||
|
import { ConfigService } from "@nestjs/config";
|
||||||
|
|
||||||
|
import { Config } from "../config/schema";
|
||||||
|
import { UtilsService } from "../utils/utils.service";
|
||||||
|
|
||||||
|
@Controller("translation")
|
||||||
|
export class TranslationController {
|
||||||
|
constructor(
|
||||||
|
private readonly httpService: HttpService,
|
||||||
|
private readonly configService: ConfigService<Config>,
|
||||||
|
private readonly utils: UtilsService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
private async fetchTranslations(locale: string) {
|
||||||
|
const distributionHash = this.configService.get("CROWDIN_DISTRIBUTION_HASH");
|
||||||
|
const response = await this.httpService.axiosRef.get(
|
||||||
|
`https://distributions.crowdin.net/${distributionHash}/content/${locale}/messages.json`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("/:locale")
|
||||||
|
@Header("Content-Type", "application/octet-stream")
|
||||||
|
@Header("Content-Disposition", 'attachment; filename="messages.po"')
|
||||||
|
async getTranslation(@Param("locale") locale: string) {
|
||||||
|
return this.utils.getCachedOrSet(
|
||||||
|
`translation:${locale}`,
|
||||||
|
async () => this.fetchTranslations(locale),
|
||||||
|
1000 * 60 * 60 * 24, // 24 hours
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
10
apps/server/src/translation/translation.module.ts
Normal file
10
apps/server/src/translation/translation.module.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { HttpModule } from "@nestjs/axios";
|
||||||
|
import { Module } from "@nestjs/common";
|
||||||
|
|
||||||
|
import { TranslationController } from "./translation.controller";
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [HttpModule],
|
||||||
|
controllers: [TranslationController],
|
||||||
|
})
|
||||||
|
export class TranslationModule {}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import { CACHE_MANAGER } from "@nestjs/cache-manager";
|
import { Injectable, InternalServerErrorException } from "@nestjs/common";
|
||||||
import { Inject, Injectable, InternalServerErrorException } from "@nestjs/common";
|
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
import { Cache } from "cache-manager";
|
import { RedisService } from "@songkeys/nestjs-redis";
|
||||||
|
import Redis from "ioredis";
|
||||||
import { PrismaService } from "nestjs-prisma";
|
import { PrismaService } from "nestjs-prisma";
|
||||||
|
|
||||||
import { ErrorMessage } from "../constants/error-message";
|
import { ErrorMessage } from "../constants/error-message";
|
||||||
@ -9,11 +9,15 @@ import { StorageService } from "../storage/storage.service";
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserService {
|
export class UserService {
|
||||||
|
private readonly redis: Redis;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly prisma: PrismaService,
|
private readonly prisma: PrismaService,
|
||||||
private readonly storageService: StorageService,
|
private readonly storageService: StorageService,
|
||||||
@Inject(CACHE_MANAGER) private readonly cache: Cache,
|
private readonly redisService: RedisService,
|
||||||
) {}
|
) {
|
||||||
|
this.redis = this.redisService.getClient();
|
||||||
|
}
|
||||||
|
|
||||||
async findOneById(id: string) {
|
async findOneById(id: string) {
|
||||||
const user = await this.prisma.user.findUniqueOrThrow({
|
const user = await this.prisma.user.findUniqueOrThrow({
|
||||||
@ -67,10 +71,7 @@ export class UserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async deleteOneById(id: string) {
|
async deleteOneById(id: string) {
|
||||||
await Promise.all([
|
await Promise.all([this.redis.del(`user:${id}:*`), this.storageService.deleteFolder(id)]);
|
||||||
...(await this.cache.store.keys(`user:${id}:*`)).map((key) => this.cache.del(key)),
|
|
||||||
this.storageService.deleteFolder(id),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return this.prisma.user.delete({ where: { id } });
|
return this.prisma.user.delete({ where: { id } });
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,18 +1,21 @@
|
|||||||
import { CACHE_MANAGER } from "@nestjs/cache-manager";
|
import { Injectable, InternalServerErrorException, Logger } from "@nestjs/common";
|
||||||
import { Inject, Injectable, InternalServerErrorException, Logger } from "@nestjs/common";
|
|
||||||
import { ConfigService } from "@nestjs/config";
|
import { ConfigService } from "@nestjs/config";
|
||||||
import { Cache } from "cache-manager";
|
import { RedisService } from "@songkeys/nestjs-redis";
|
||||||
|
import Redis from "ioredis";
|
||||||
|
|
||||||
import { Config } from "../config/schema";
|
import { Config } from "../config/schema";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UtilsService {
|
export class UtilsService {
|
||||||
|
private readonly redis: Redis;
|
||||||
logger = new Logger(UtilsService.name);
|
logger = new Logger(UtilsService.name);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
private readonly redisService: RedisService,
|
||||||
private readonly configService: ConfigService<Config>,
|
private readonly configService: ConfigService<Config>,
|
||||||
@Inject(CACHE_MANAGER) private readonly cache: Cache,
|
) {
|
||||||
) {}
|
this.redis = this.redisService.getClient();
|
||||||
|
}
|
||||||
|
|
||||||
getUrl(): string {
|
getUrl(): string {
|
||||||
const url =
|
const url =
|
||||||
@ -27,28 +30,34 @@ export class UtilsService {
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getCachedOrSet<T>(key: string, callback: () => Promise<T>, ttl?: number): Promise<T> {
|
async getCachedOrSet<T>(
|
||||||
|
key: string,
|
||||||
|
callback: () => Promise<T> | T,
|
||||||
|
ttl: number = 1000 * 60 * 60 * 24, // 24 hours
|
||||||
|
type: "json" | "string" = "json",
|
||||||
|
): Promise<T> {
|
||||||
// Try to get the value from the cache
|
// Try to get the value from the cache
|
||||||
const start = performance.now();
|
const start = performance.now();
|
||||||
const cachedValue = await this.cache.get<T>(key);
|
const cachedValue = await this.redis.get(key);
|
||||||
const duration = Number(performance.now() - start).toFixed(0);
|
const duration = Number(performance.now() - start).toFixed(0);
|
||||||
|
|
||||||
if (cachedValue === undefined) {
|
if (!cachedValue) {
|
||||||
this.logger.debug(`Cache Key "${key}": miss`);
|
this.logger.debug(`Cache Key "${key}": miss`);
|
||||||
} else {
|
} else {
|
||||||
this.logger.debug(`Cache Key "${key}": hit - ${duration}ms`);
|
this.logger.debug(`Cache Key "${key}": hit - ${duration}ms`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the value is in the cache, return it
|
// If the value is in the cache, return it
|
||||||
if (cachedValue !== undefined) {
|
if (cachedValue) {
|
||||||
return cachedValue;
|
return (type === "string" ? cachedValue : JSON.parse(cachedValue)) as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the value is not in the cache, run the callback
|
// If the value is not in the cache, run the callback
|
||||||
const value = await callback();
|
const value = await callback();
|
||||||
|
const valueToCache = (type === "string" ? value : JSON.stringify(value)) as string;
|
||||||
|
|
||||||
// Store the value in the cache
|
// Store the value in the cache
|
||||||
await this.cache.set(key, value, ttl);
|
await this.redis.set(key, valueToCache, "PX", ttl);
|
||||||
|
|
||||||
// Return the value
|
// Return the value
|
||||||
return value;
|
return value;
|
||||||
|
|||||||
@ -131,7 +131,6 @@
|
|||||||
"@lingui/react": "^4.5.0",
|
"@lingui/react": "^4.5.0",
|
||||||
"@nestjs-modules/mailer": "^1.9.1",
|
"@nestjs-modules/mailer": "^1.9.1",
|
||||||
"@nestjs/axios": "^3.0.1",
|
"@nestjs/axios": "^3.0.1",
|
||||||
"@nestjs/cache-manager": "^2.1.1",
|
|
||||||
"@nestjs/common": "^10.2.8",
|
"@nestjs/common": "^10.2.8",
|
||||||
"@nestjs/config": "^3.1.1",
|
"@nestjs/config": "^3.1.1",
|
||||||
"@nestjs/core": "^10.2.8",
|
"@nestjs/core": "^10.2.8",
|
||||||
@ -186,8 +185,6 @@
|
|||||||
"axios": "^1.6.1",
|
"axios": "^1.6.1",
|
||||||
"axios-auth-refresh": "^3.3.6",
|
"axios-auth-refresh": "^3.3.6",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
"cache-manager": "^5.2.4",
|
|
||||||
"cache-manager-redis-yet": "^4.1.2",
|
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.0.0",
|
"clsx": "^2.0.0",
|
||||||
"cmdk": "^0.2.0",
|
"cmdk": "^0.2.0",
|
||||||
|
|||||||
179
pnpm-lock.yaml
generated
179
pnpm-lock.yaml
generated
@ -41,9 +41,6 @@ dependencies:
|
|||||||
'@nestjs/axios':
|
'@nestjs/axios':
|
||||||
specifier: ^3.0.1
|
specifier: ^3.0.1
|
||||||
version: 3.0.1(@nestjs/common@10.2.8)(axios@1.6.1)(reflect-metadata@0.1.13)(rxjs@7.8.1)
|
version: 3.0.1(@nestjs/common@10.2.8)(axios@1.6.1)(reflect-metadata@0.1.13)(rxjs@7.8.1)
|
||||||
'@nestjs/cache-manager':
|
|
||||||
specifier: ^2.1.1
|
|
||||||
version: 2.1.1(@nestjs/common@10.2.8)(@nestjs/core@10.2.8)(cache-manager@5.2.4)(reflect-metadata@0.1.13)(rxjs@7.8.1)
|
|
||||||
'@nestjs/common':
|
'@nestjs/common':
|
||||||
specifier: ^10.2.8
|
specifier: ^10.2.8
|
||||||
version: 10.2.8(reflect-metadata@0.1.13)(rxjs@7.8.1)
|
version: 10.2.8(reflect-metadata@0.1.13)(rxjs@7.8.1)
|
||||||
@ -206,12 +203,6 @@ dependencies:
|
|||||||
bcryptjs:
|
bcryptjs:
|
||||||
specifier: ^2.4.3
|
specifier: ^2.4.3
|
||||||
version: 2.4.3
|
version: 2.4.3
|
||||||
cache-manager:
|
|
||||||
specifier: ^5.2.4
|
|
||||||
version: 5.2.4
|
|
||||||
cache-manager-redis-yet:
|
|
||||||
specifier: ^4.1.2
|
|
||||||
version: 4.1.2
|
|
||||||
class-variance-authority:
|
class-variance-authority:
|
||||||
specifier: ^0.7.0
|
specifier: ^0.7.0
|
||||||
version: 0.7.0
|
version: 0.7.0
|
||||||
@ -2164,16 +2155,6 @@ packages:
|
|||||||
conventional-changelog-conventionalcommits: 7.0.2
|
conventional-changelog-conventionalcommits: 7.0.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@commitlint/config-validator@18.1.0:
|
|
||||||
resolution: {integrity: sha512-kbHkIuItXn93o2NmTdwi5Mk1ujyuSIysRE/XHtrcps/27GuUKEIqBJp6TdJ4Sq+ze59RlzYSHMKuDKZbfg9+uQ==}
|
|
||||||
engines: {node: '>=v18'}
|
|
||||||
requiresBuild: true
|
|
||||||
dependencies:
|
|
||||||
'@commitlint/types': 18.1.0
|
|
||||||
ajv: 8.12.0
|
|
||||||
dev: true
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
/@commitlint/config-validator@18.4.0:
|
/@commitlint/config-validator@18.4.0:
|
||||||
resolution: {integrity: sha512-1y6qHMU3o4cYQSK+Y9EnmH6H1GRiwQGjnLIUOIKlekrmfc8MrMk1ByNmb8od4vK3qHJAaL/77/5n+1uyyIF5dA==}
|
resolution: {integrity: sha512-1y6qHMU3o4cYQSK+Y9EnmH6H1GRiwQGjnLIUOIKlekrmfc8MrMk1ByNmb8od4vK3qHJAaL/77/5n+1uyyIF5dA==}
|
||||||
engines: {node: '>=v18'}
|
engines: {node: '>=v18'}
|
||||||
@ -2194,13 +2175,6 @@ packages:
|
|||||||
lodash.upperfirst: 4.3.1
|
lodash.upperfirst: 4.3.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@commitlint/execute-rule@18.1.0:
|
|
||||||
resolution: {integrity: sha512-w3Vt4K+O7+nSr9/gFSEfZ1exKUOPSlJaRpnk7Y+XowEhvwT7AIk1HNANH+gETf0zGZ020+hfiMW/Ome+SNCUsg==}
|
|
||||||
engines: {node: '>=v18'}
|
|
||||||
requiresBuild: true
|
|
||||||
dev: true
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
/@commitlint/execute-rule@18.4.0:
|
/@commitlint/execute-rule@18.4.0:
|
||||||
resolution: {integrity: sha512-g013SWki6ZWhURBLOSXTaVQGWHdA0QlPJGiW4a+YpThezmJOemvc4LiKVpn13AjSKQ40QnmBqpBrxujOaSo+3A==}
|
resolution: {integrity: sha512-g013SWki6ZWhURBLOSXTaVQGWHdA0QlPJGiW4a+YpThezmJOemvc4LiKVpn13AjSKQ40QnmBqpBrxujOaSo+3A==}
|
||||||
engines: {node: '>=v18'}
|
engines: {node: '>=v18'}
|
||||||
@ -2232,28 +2206,6 @@ packages:
|
|||||||
'@commitlint/types': 18.4.0
|
'@commitlint/types': 18.4.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@commitlint/load@18.2.0(typescript@5.2.2):
|
|
||||||
resolution: {integrity: sha512-xjX3d3CRlOALwImhOsmLYZh14/+gW/KxsY7+bPKrzmGuFailf9K7ckhB071oYZVJdACnpY4hDYiosFyOC+MpAA==}
|
|
||||||
engines: {node: '>=v18'}
|
|
||||||
requiresBuild: true
|
|
||||||
dependencies:
|
|
||||||
'@commitlint/config-validator': 18.1.0
|
|
||||||
'@commitlint/execute-rule': 18.1.0
|
|
||||||
'@commitlint/resolve-extends': 18.1.0
|
|
||||||
'@commitlint/types': 18.1.0
|
|
||||||
'@types/node': 18.18.8
|
|
||||||
chalk: 4.1.2
|
|
||||||
cosmiconfig: 8.3.6(typescript@5.2.2)
|
|
||||||
cosmiconfig-typescript-loader: 5.0.0(@types/node@18.18.8)(cosmiconfig@8.3.6)(typescript@5.2.2)
|
|
||||||
lodash.isplainobject: 4.0.6
|
|
||||||
lodash.merge: 4.6.2
|
|
||||||
lodash.uniq: 4.5.0
|
|
||||||
resolve-from: 5.0.0
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- typescript
|
|
||||||
dev: true
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
/@commitlint/load@18.4.0(typescript@5.2.2):
|
/@commitlint/load@18.4.0(typescript@5.2.2):
|
||||||
resolution: {integrity: sha512-7unGl1HGRNMgWrUPmj8OFkJyuNUMb6xA1i53/OAFKd9l+U3C4WTfoJe3t/TUz8vKZLCaDcWWR/b2cw5HveBBFg==}
|
resolution: {integrity: sha512-7unGl1HGRNMgWrUPmj8OFkJyuNUMb6xA1i53/OAFKd9l+U3C4WTfoJe3t/TUz8vKZLCaDcWWR/b2cw5HveBBFg==}
|
||||||
engines: {node: '>=v18'}
|
engines: {node: '>=v18'}
|
||||||
@ -2299,20 +2251,6 @@ packages:
|
|||||||
minimist: 1.2.8
|
minimist: 1.2.8
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@commitlint/resolve-extends@18.1.0:
|
|
||||||
resolution: {integrity: sha512-3mZpzOEJkELt7BbaZp6+bofJyxViyObebagFn0A7IHaLARhPkWTivXdjvZHS12nAORftv88Yhbh8eCPKfSvB7g==}
|
|
||||||
engines: {node: '>=v18'}
|
|
||||||
requiresBuild: true
|
|
||||||
dependencies:
|
|
||||||
'@commitlint/config-validator': 18.1.0
|
|
||||||
'@commitlint/types': 18.1.0
|
|
||||||
import-fresh: 3.3.0
|
|
||||||
lodash.mergewith: 4.6.2
|
|
||||||
resolve-from: 5.0.0
|
|
||||||
resolve-global: 1.0.0
|
|
||||||
dev: true
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
/@commitlint/resolve-extends@18.4.0:
|
/@commitlint/resolve-extends@18.4.0:
|
||||||
resolution: {integrity: sha512-qhgU6ach+S6sJMD9NjCYiEycOObGhxzWQLQzqlScJCv9zkPs15Bg0ffLXTQ3z7ipXv46XEKYMnSJzjLRw2Tlkg==}
|
resolution: {integrity: sha512-qhgU6ach+S6sJMD9NjCYiEycOObGhxzWQLQzqlScJCv9zkPs15Bg0ffLXTQ3z7ipXv46XEKYMnSJzjLRw2Tlkg==}
|
||||||
engines: {node: '>=v18'}
|
engines: {node: '>=v18'}
|
||||||
@ -2348,15 +2286,6 @@ packages:
|
|||||||
find-up: 5.0.0
|
find-up: 5.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@commitlint/types@18.1.0:
|
|
||||||
resolution: {integrity: sha512-65vGxZmbs+2OVwEItxhp3Ul7X2m2LyLfifYI/NdPwRqblmuES2w2aIRhIjb7cwUIBHHSTT8WXj4ixVHQibmvLQ==}
|
|
||||||
engines: {node: '>=v18'}
|
|
||||||
requiresBuild: true
|
|
||||||
dependencies:
|
|
||||||
chalk: 4.1.2
|
|
||||||
dev: true
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
/@commitlint/types@18.4.0:
|
/@commitlint/types@18.4.0:
|
||||||
resolution: {integrity: sha512-MKeaFxt0I9fhqUb2E+YIzX/gZtmkuodJET/XKiZIMvXUff8Ee4Ih86eLg+yAm2jf1pwGBmU02uNOp0y094w2Uw==}
|
resolution: {integrity: sha512-MKeaFxt0I9fhqUb2E+YIzX/gZtmkuodJET/XKiZIMvXUff8Ee4Ih86eLg+yAm2jf1pwGBmU02uNOp0y094w2Uw==}
|
||||||
engines: {node: '>=v18'}
|
engines: {node: '>=v18'}
|
||||||
@ -3564,22 +3493,6 @@ packages:
|
|||||||
rxjs: 7.8.1
|
rxjs: 7.8.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@nestjs/cache-manager@2.1.1(@nestjs/common@10.2.8)(@nestjs/core@10.2.8)(cache-manager@5.2.4)(reflect-metadata@0.1.13)(rxjs@7.8.1):
|
|
||||||
resolution: {integrity: sha512-oYfRys4Ng0zp2HTUPNjH7gizf4vvG3PQZZ+3yGemb3xrF+p3JxDSK0cDq9NTjHzD5UmhjiyAftB9GkuL+t3r9g==}
|
|
||||||
peerDependencies:
|
|
||||||
'@nestjs/common': ^9.0.0 || ^10.0.0
|
|
||||||
'@nestjs/core': ^9.0.0 || ^10.0.0
|
|
||||||
cache-manager: <=5
|
|
||||||
reflect-metadata: ^0.1.12
|
|
||||||
rxjs: ^7.0.0
|
|
||||||
dependencies:
|
|
||||||
'@nestjs/common': 10.2.8(reflect-metadata@0.1.13)(rxjs@7.8.1)
|
|
||||||
'@nestjs/core': 10.2.8(@nestjs/common@10.2.8)(@nestjs/platform-express@10.2.8)(reflect-metadata@0.1.13)(rxjs@7.8.1)
|
|
||||||
cache-manager: 5.2.4
|
|
||||||
reflect-metadata: 0.1.13
|
|
||||||
rxjs: 7.8.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@nestjs/common@10.2.8(reflect-metadata@0.1.13)(rxjs@7.8.1):
|
/@nestjs/common@10.2.8(reflect-metadata@0.1.13)(rxjs@7.8.1):
|
||||||
resolution: {integrity: sha512-rmpwcdvq2IWMmsUVP8rsdKub6uDWk7dwCYo0aif50JTwcvcxzaP3iKVFKoSgvp0RKYu8h15+/AEOfaInmPpl0Q==}
|
resolution: {integrity: sha512-rmpwcdvq2IWMmsUVP8rsdKub6uDWk7dwCYo0aif50JTwcvcxzaP3iKVFKoSgvp0RKYu8h15+/AEOfaInmPpl0Q==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -6131,55 +6044,6 @@ packages:
|
|||||||
'@babel/runtime': 7.23.2
|
'@babel/runtime': 7.23.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@redis/bloom@1.2.0(@redis/client@1.5.11):
|
|
||||||
resolution: {integrity: sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==}
|
|
||||||
peerDependencies:
|
|
||||||
'@redis/client': ^1.0.0
|
|
||||||
dependencies:
|
|
||||||
'@redis/client': 1.5.11
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@redis/client@1.5.11:
|
|
||||||
resolution: {integrity: sha512-cV7yHcOAtNQ5x/yQl7Yw1xf53kO0FNDTdDU6bFIMbW6ljB7U7ns0YRM+QIkpoqTAt6zK5k9Fq0QWlUbLcq9AvA==}
|
|
||||||
engines: {node: '>=14'}
|
|
||||||
dependencies:
|
|
||||||
cluster-key-slot: 1.1.2
|
|
||||||
generic-pool: 3.9.0
|
|
||||||
yallist: 4.0.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@redis/graph@1.1.0(@redis/client@1.5.11):
|
|
||||||
resolution: {integrity: sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg==}
|
|
||||||
peerDependencies:
|
|
||||||
'@redis/client': ^1.0.0
|
|
||||||
dependencies:
|
|
||||||
'@redis/client': 1.5.11
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@redis/json@1.0.6(@redis/client@1.5.11):
|
|
||||||
resolution: {integrity: sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==}
|
|
||||||
peerDependencies:
|
|
||||||
'@redis/client': ^1.0.0
|
|
||||||
dependencies:
|
|
||||||
'@redis/client': 1.5.11
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@redis/search@1.1.5(@redis/client@1.5.11):
|
|
||||||
resolution: {integrity: sha512-hPP8w7GfGsbtYEJdn4n7nXa6xt6hVZnnDktKW4ArMaFQ/m/aR7eFvsLQmG/mn1Upq99btPJk+F27IQ2dYpCoUg==}
|
|
||||||
peerDependencies:
|
|
||||||
'@redis/client': ^1.0.0
|
|
||||||
dependencies:
|
|
||||||
'@redis/client': 1.5.11
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@redis/time-series@1.0.5(@redis/client@1.5.11):
|
|
||||||
resolution: {integrity: sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==}
|
|
||||||
peerDependencies:
|
|
||||||
'@redis/client': ^1.0.0
|
|
||||||
dependencies:
|
|
||||||
'@redis/client': 1.5.11
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@remirror/core-constants@2.0.2:
|
/@remirror/core-constants@2.0.2:
|
||||||
resolution: {integrity: sha512-dyHY+sMF0ihPus3O27ODd4+agdHMEmuRdyiZJ2CCWjPV5UFmn17ZbElvk6WOGVE4rdCJKZQCrPV2BcikOMLUGQ==}
|
resolution: {integrity: sha512-dyHY+sMF0ihPus3O27ODd4+agdHMEmuRdyiZJ2CCWjPV5UFmn17ZbElvk6WOGVE4rdCJKZQCrPV2BcikOMLUGQ==}
|
||||||
dev: false
|
dev: false
|
||||||
@ -9064,27 +8928,6 @@ packages:
|
|||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/cache-manager-redis-yet@4.1.2:
|
|
||||||
resolution: {integrity: sha512-pM2K1ZlOv8gQpE1Z5mcDrfLj5CsNKVRiYua/SZ12j7LEDgfDeFVntI6JSgIw0siFSR/9P/FpG30scI3frHwibA==}
|
|
||||||
engines: {node: '>= 16.17.0'}
|
|
||||||
dependencies:
|
|
||||||
'@redis/bloom': 1.2.0(@redis/client@1.5.11)
|
|
||||||
'@redis/client': 1.5.11
|
|
||||||
'@redis/graph': 1.1.0(@redis/client@1.5.11)
|
|
||||||
'@redis/json': 1.0.6(@redis/client@1.5.11)
|
|
||||||
'@redis/search': 1.1.5(@redis/client@1.5.11)
|
|
||||||
'@redis/time-series': 1.0.5(@redis/client@1.5.11)
|
|
||||||
cache-manager: 5.2.4
|
|
||||||
redis: 4.6.10
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/cache-manager@5.2.4:
|
|
||||||
resolution: {integrity: sha512-gkuCjug16NdGvKm/sydxGVx17uffrSWcEe2xraBtwRCgdYcFxwJAla4OYpASAZT2yhSoxgDiWL9XH6IAChcZJA==}
|
|
||||||
dependencies:
|
|
||||||
lodash.clonedeep: 4.5.0
|
|
||||||
lru-cache: 10.0.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/cacheable-lookup@5.0.4:
|
/cacheable-lookup@5.0.4:
|
||||||
resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==}
|
resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==}
|
||||||
engines: {node: '>=10.6.0'}
|
engines: {node: '>=10.6.0'}
|
||||||
@ -10151,7 +9994,7 @@ packages:
|
|||||||
longest: 2.0.1
|
longest: 2.0.1
|
||||||
word-wrap: 1.2.5
|
word-wrap: 1.2.5
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@commitlint/load': 18.2.0(typescript@5.2.2)
|
'@commitlint/load': 18.4.0(typescript@5.2.2)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- typescript
|
- typescript
|
||||||
dev: true
|
dev: true
|
||||||
@ -12069,11 +11912,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
|
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/generic-pool@3.9.0:
|
|
||||||
resolution: {integrity: sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==}
|
|
||||||
engines: {node: '>= 4'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/gensync@1.0.0-beta.2:
|
/gensync@1.0.0-beta.2:
|
||||||
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
|
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
@ -14359,10 +14197,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==}
|
resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/lodash.clonedeep@4.5.0:
|
|
||||||
resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/lodash.debounce@4.0.8:
|
/lodash.debounce@4.0.8:
|
||||||
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
|
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
|
||||||
|
|
||||||
@ -17670,17 +17504,6 @@ packages:
|
|||||||
redis-errors: 1.2.0
|
redis-errors: 1.2.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/redis@4.6.10:
|
|
||||||
resolution: {integrity: sha512-mmbyhuKgDiJ5TWUhiKhBssz+mjsuSI/lSZNPI9QvZOYzWvYGejtb+W3RlDDf8LD6Bdl5/mZeG8O1feUGhXTxEg==}
|
|
||||||
dependencies:
|
|
||||||
'@redis/bloom': 1.2.0(@redis/client@1.5.11)
|
|
||||||
'@redis/client': 1.5.11
|
|
||||||
'@redis/graph': 1.1.0(@redis/client@1.5.11)
|
|
||||||
'@redis/json': 1.0.6(@redis/client@1.5.11)
|
|
||||||
'@redis/search': 1.1.5(@redis/client@1.5.11)
|
|
||||||
'@redis/time-series': 1.0.5(@redis/client@1.5.11)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/reflect-metadata@0.1.13:
|
/reflect-metadata@0.1.13:
|
||||||
resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==}
|
resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==}
|
||||||
|
|
||||||
|
|||||||
@ -18,12 +18,12 @@
|
|||||||
"@/client/*": ["apps/client/src/*"],
|
"@/client/*": ["apps/client/src/*"],
|
||||||
"@/server/*": ["apps/server/src/*"],
|
"@/server/*": ["apps/server/src/*"],
|
||||||
"@/artboard/*": ["apps/artboard/src/*"],
|
"@/artboard/*": ["apps/artboard/src/*"],
|
||||||
|
"@reactive-resume/ui": ["libs/ui/src/index.ts"],
|
||||||
"@reactive-resume/dto": ["libs/dto/src/index.ts"],
|
"@reactive-resume/dto": ["libs/dto/src/index.ts"],
|
||||||
|
"@reactive-resume/utils": ["libs/utils/src/index.ts"],
|
||||||
"@reactive-resume/hooks": ["libs/hooks/src/index.ts"],
|
"@reactive-resume/hooks": ["libs/hooks/src/index.ts"],
|
||||||
"@reactive-resume/parser": ["libs/parser/src/index.ts"],
|
"@reactive-resume/parser": ["libs/parser/src/index.ts"],
|
||||||
"@reactive-resume/schema": ["libs/schema/src/index.ts"],
|
"@reactive-resume/schema": ["libs/schema/src/index.ts"]
|
||||||
"@reactive-resume/ui": ["libs/ui/src/index.ts"],
|
|
||||||
"@reactive-resume/utils": ["libs/utils/src/index.ts"]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules", "dist", "tmp", ".nx"]
|
"exclude": ["node_modules", "dist", "tmp", ".nx"]
|
||||||
|
|||||||
Reference in New Issue
Block a user