mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-13 08:13:49 +10:00
feat(i18n): translate error messages
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -25,9 +25,9 @@ import {
|
||||
userSchema,
|
||||
UserWithSecrets,
|
||||
} from "@reactive-resume/dto";
|
||||
import { ErrorMessage } from "@reactive-resume/utils";
|
||||
import type { Response } from "express";
|
||||
|
||||
import { ErrorMessage } from "../constants/error-message";
|
||||
import { User } from "../user/decorators/user.decorator";
|
||||
import { UtilsService } from "../utils/utils.service";
|
||||
import { AuthService } from "./auth.service";
|
||||
|
||||
@ -8,12 +8,12 @@ import { ConfigService } from "@nestjs/config";
|
||||
import { JwtService } from "@nestjs/jwt";
|
||||
import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library";
|
||||
import { LoginDto, RegisterDto } from "@reactive-resume/dto";
|
||||
import { ErrorMessage } from "@reactive-resume/utils";
|
||||
import * as bcryptjs from "bcryptjs";
|
||||
import { randomBytes } from "crypto";
|
||||
import { authenticator } from "otplib";
|
||||
|
||||
import { Config } from "../config/schema";
|
||||
import { ErrorMessage } from "../constants/error-message";
|
||||
import { MailService } from "../mail/mail.service";
|
||||
import { UserService } from "../user/user.service";
|
||||
import { UtilsService } from "../utils/utils.service";
|
||||
|
||||
@ -2,9 +2,9 @@ import { BadRequestException, Injectable, UnauthorizedException } from "@nestjs/
|
||||
import { PassportStrategy } from "@nestjs/passport";
|
||||
import { User } from "@prisma/client";
|
||||
import { processUsername } from "@reactive-resume/utils";
|
||||
import { ErrorMessage } from "@reactive-resume/utils";
|
||||
import { Profile, Strategy, StrategyOptions } from "passport-github2";
|
||||
|
||||
import { ErrorMessage } from "@/server/constants/error-message";
|
||||
import { UserService } from "@/server/user/user.service";
|
||||
|
||||
@Injectable()
|
||||
|
||||
@ -2,9 +2,9 @@ import { BadRequestException, Injectable, UnauthorizedException } from "@nestjs/
|
||||
import { PassportStrategy } from "@nestjs/passport";
|
||||
import { User } from "@prisma/client";
|
||||
import { processUsername } from "@reactive-resume/utils";
|
||||
import { ErrorMessage } from "@reactive-resume/utils";
|
||||
import { Profile, Strategy, StrategyOptions, VerifyCallback } from "passport-google-oauth20";
|
||||
|
||||
import { ErrorMessage } from "@/server/constants/error-message";
|
||||
import { UserService } from "@/server/user/user.service";
|
||||
|
||||
@Injectable()
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import { BadRequestException, Injectable } from "@nestjs/common";
|
||||
import { PassportStrategy } from "@nestjs/passport";
|
||||
import { ErrorMessage } from "@reactive-resume/utils";
|
||||
import { IStrategyOptions, Strategy } from "passport-local";
|
||||
|
||||
import { ErrorMessage } from "@/server/constants/error-message";
|
||||
|
||||
import { AuthService } from "../auth.service";
|
||||
|
||||
@Injectable()
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
export const ErrorMessage = {
|
||||
InvalidCredentials: "It doesn't look like a user exists with the credentials you provided.",
|
||||
UserAlreadyExists: "A user with this email address and/or username already exists.",
|
||||
SecretsNotFound:
|
||||
'User does not have an associated "secrets" record. Please report this issue on GitHub.',
|
||||
OAuthUser:
|
||||
"This email address is associated with an OAuth account. Please sign in with your OAuth provider.",
|
||||
InvalidResetToken:
|
||||
"It looks like the reset token you provided is invalid. Please try restarting the password reset process again.",
|
||||
InvalidVerificationToken:
|
||||
"It looks like the verification token you provided is invalid. Please try restarting the verification process again.",
|
||||
EmailAlreadyVerified: "It looks like your email address has already been verified.",
|
||||
TwoFactorNotEnabled: "Two-factor authentication is not enabled for this account.",
|
||||
TwoFactorAlreadyEnabled: "Two-factor authentication is already enabled for this account.",
|
||||
InvalidTwoFactorCode:
|
||||
"It looks like the two-factor authentication code you provided is invalid. Please try again.",
|
||||
InvalidTwoFactorBackupCode:
|
||||
"It looks like the backup code you provided is invalid or used. Please try again.",
|
||||
InvalidBrowserConnection:
|
||||
"There was an error connecting to the browser. Please make sure `chrome` is running and reachable.",
|
||||
ResumeSlugAlreadyExists:
|
||||
"A resume with this slug already exists, please pick a different unique identifier.",
|
||||
ResumeNotFound: "It looks like the resume you're looking for doesn't exist.",
|
||||
ResumeLocked:
|
||||
"The resume you want to update is locked, please unlock if you wish to make any changes to it.",
|
||||
ResumePrinterError:
|
||||
"Something went wrong while printing your resume. Please try again later or raise an issue on GitHub.",
|
||||
ResumePreviewError:
|
||||
"Something went wrong while grabbing a preview your resume. Please try again later or raise an issue on GitHub.",
|
||||
SomethingWentWrong:
|
||||
"Something went wrong while processing your request. Please try again later or raise an issue on GitHub.",
|
||||
} as const;
|
||||
|
||||
export type ErrorMessage = typeof ErrorMessage;
|
||||
File diff suppressed because it is too large
Load Diff
@ -5,12 +5,12 @@ import { ConfigService } from "@nestjs/config";
|
||||
import fontkit from "@pdf-lib/fontkit";
|
||||
import { ResumeDto } from "@reactive-resume/dto";
|
||||
import { getFontUrls, withTimeout } from "@reactive-resume/utils";
|
||||
import { ErrorMessage } from "@reactive-resume/utils";
|
||||
import retry from "async-retry";
|
||||
import { PDFDocument } from "pdf-lib";
|
||||
import { connect } from "puppeteer";
|
||||
|
||||
import { Config } from "../config/schema";
|
||||
import { ErrorMessage } from "../constants/error-message";
|
||||
import { StorageService } from "../storage/storage.service";
|
||||
import { UtilsService } from "../utils/utils.service";
|
||||
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import { CanActivate, ExecutionContext, Injectable, NotFoundException } from "@nestjs/common";
|
||||
import { UserWithSecrets } from "@reactive-resume/dto";
|
||||
import { ErrorMessage } from "@reactive-resume/utils";
|
||||
import { Request } from "express";
|
||||
|
||||
import { ErrorMessage } from "@/server/constants/error-message";
|
||||
|
||||
import { ResumeService } from "../resume.service";
|
||||
|
||||
@Injectable()
|
||||
|
||||
@ -16,13 +16,13 @@ import { User as UserEntity } from "@prisma/client";
|
||||
import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library";
|
||||
import { CreateResumeDto, ImportResumeDto, ResumeDto, UpdateResumeDto } from "@reactive-resume/dto";
|
||||
import { resumeDataSchema } from "@reactive-resume/schema";
|
||||
import { ErrorMessage } from "@reactive-resume/utils";
|
||||
import { zodToJsonSchema } from "zod-to-json-schema";
|
||||
|
||||
import { User } from "@/server/user/decorators/user.decorator";
|
||||
|
||||
import { OptionalGuard } from "../auth/guards/optional.guard";
|
||||
import { TwoFactorGuard } from "../auth/guards/two-factor.guard";
|
||||
import { ErrorMessage } from "../constants/error-message";
|
||||
import { UtilsService } from "../utils/utils.service";
|
||||
import { Resume } from "./decorators/resume.decorator";
|
||||
import { ResumeGuard } from "./guards/resume.guard";
|
||||
|
||||
@ -4,6 +4,7 @@ import { CreateResumeDto, ImportResumeDto, ResumeDto, UpdateResumeDto } from "@r
|
||||
import { defaultResumeData, ResumeData } from "@reactive-resume/schema";
|
||||
import type { DeepPartial } from "@reactive-resume/utils";
|
||||
import { generateRandomName, kebabCase } from "@reactive-resume/utils";
|
||||
import { ErrorMessage } from "@reactive-resume/utils";
|
||||
import { RedisService } from "@songkeys/nestjs-redis";
|
||||
import deepmerge from "deepmerge";
|
||||
import Redis from "ioredis";
|
||||
@ -11,7 +12,6 @@ import { PrismaService } from "nestjs-prisma";
|
||||
|
||||
import { PrinterService } from "@/server/printer/printer.service";
|
||||
|
||||
import { ErrorMessage } from "../constants/error-message";
|
||||
import { StorageService } from "../storage/storage.service";
|
||||
import { UtilsService } from "../utils/utils.service";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Controller, Get, Param } from "@nestjs/common";
|
||||
import { Controller, Get } from "@nestjs/common";
|
||||
|
||||
import { UtilsService } from "../utils/utils.service";
|
||||
import { TranslationService } from "./translation.service";
|
||||
@ -18,13 +18,4 @@ export class TranslationController {
|
||||
1000 * 60 * 60 * 24, // 24 hours
|
||||
);
|
||||
}
|
||||
|
||||
@Get("/:locale")
|
||||
async translation(@Param("locale") locale: string) {
|
||||
return this.utils.getCachedOrSet(
|
||||
`translation:${locale}`,
|
||||
async () => this.translationService.fetchTranslations(locale),
|
||||
1000 * 60 * 60 * 24, // 24 hours
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { HttpService } from "@nestjs/axios";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { ConfigService } from "@nestjs/config";
|
||||
import { LanguageDto } from "@reactive-resume/dto";
|
||||
import { Language, languages } from "@reactive-resume/utils";
|
||||
|
||||
import { Config } from "../config/schema";
|
||||
|
||||
@ -21,48 +21,44 @@ export class TranslationService {
|
||||
private readonly configService: ConfigService<Config>,
|
||||
) {}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
async fetchLanguages() {
|
||||
const isDevelopment = this.configService.get("NODE_ENV") === "development";
|
||||
const projectId = this.configService.get("CROWDIN_PROJECT_ID");
|
||||
const accessToken = this.configService.get("CROWDIN_ACCESS_TOKEN");
|
||||
|
||||
const response = await this.httpService.axiosRef.get(
|
||||
`https://api.crowdin.com/api/v2/projects/${projectId}/languages/progress?limit=100`,
|
||||
{ headers: { Authorization: `Bearer ${accessToken}` } },
|
||||
);
|
||||
const { data } = response.data as CrowdinResponse;
|
||||
try {
|
||||
const projectId = this.configService.getOrThrow("CROWDIN_PROJECT_ID");
|
||||
const accessToken = this.configService.getOrThrow("CROWDIN_ACCESS_TOKEN");
|
||||
|
||||
if (isDevelopment) {
|
||||
data.push({
|
||||
data: {
|
||||
language: {
|
||||
id: "zu-ZA",
|
||||
locale: "zu-ZA",
|
||||
editorCode: "zuza",
|
||||
name: "Psuedo Locale",
|
||||
const response = await this.httpService.axiosRef.get(
|
||||
`https://api.crowdin.com/api/v2/projects/${projectId}/languages/progress?limit=100`,
|
||||
{ headers: { Authorization: `Bearer ${accessToken}` } },
|
||||
);
|
||||
const { data } = response.data as CrowdinResponse;
|
||||
|
||||
if (isDevelopment) {
|
||||
data.push({
|
||||
data: {
|
||||
language: {
|
||||
id: "zu-ZA",
|
||||
locale: "zu-ZA",
|
||||
editorCode: "zuza",
|
||||
name: "Psuedo Locale",
|
||||
},
|
||||
translationProgress: 100,
|
||||
},
|
||||
translationProgress: 100,
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return data.map(({ data }) => {
|
||||
return {
|
||||
id: data.language.id,
|
||||
name: data.language.name,
|
||||
progress: data.translationProgress,
|
||||
editorCode: data.language.editorCode,
|
||||
locale: data.language.locale,
|
||||
} satisfies LanguageDto;
|
||||
});
|
||||
return data.map(({ data }) => {
|
||||
return {
|
||||
id: data.language.id,
|
||||
name: data.language.name,
|
||||
progress: data.translationProgress,
|
||||
editorCode: data.language.editorCode,
|
||||
locale: data.language.locale,
|
||||
} satisfies Language;
|
||||
});
|
||||
} catch (error) {
|
||||
return languages;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { Injectable, InternalServerErrorException } from "@nestjs/common";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { ErrorMessage } from "@reactive-resume/utils";
|
||||
import { RedisService } from "@songkeys/nestjs-redis";
|
||||
import Redis from "ioredis";
|
||||
import { PrismaService } from "nestjs-prisma";
|
||||
|
||||
import { ErrorMessage } from "../constants/error-message";
|
||||
import { StorageService } from "../storage/storage.service";
|
||||
|
||||
@Injectable()
|
||||
|
||||
Reference in New Issue
Block a user