mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-09-22 19:53:48 +08:00
@@ -1,7 +1,6 @@
|
|||||||
import { STATUS_CODES } from 'node:http';
|
import { STATUS_CODES } from 'node:http';
|
||||||
|
|
||||||
import { HttpStatus, Logger } from '@nestjs/common';
|
import { HttpStatus, Logger } from '@nestjs/common';
|
||||||
import { capitalize } from 'lodash-es';
|
|
||||||
import { ClsServiceManager } from 'nestjs-cls';
|
import { ClsServiceManager } from 'nestjs-cls';
|
||||||
|
|
||||||
export type UserFriendlyErrorBaseType =
|
export type UserFriendlyErrorBaseType =
|
||||||
@@ -17,7 +16,7 @@ export type UserFriendlyErrorBaseType =
|
|||||||
| 'internal_server_error';
|
| 'internal_server_error';
|
||||||
|
|
||||||
type ErrorArgType = 'string' | 'number' | 'boolean';
|
type ErrorArgType = 'string' | 'number' | 'boolean';
|
||||||
type ErrorArgs = Record<string, ErrorArgType | Record<string, ErrorArgType>>;
|
type ErrorArgs = Record<string, ErrorArgType>;
|
||||||
|
|
||||||
export type UserFriendlyErrorOptions = {
|
export type UserFriendlyErrorOptions = {
|
||||||
type: UserFriendlyErrorBaseType;
|
type: UserFriendlyErrorBaseType;
|
||||||
@@ -152,25 +151,14 @@ export class UserFriendlyError extends Error {
|
|||||||
* @ObjectType()
|
* @ObjectType()
|
||||||
* export class XXXDataType {
|
* export class XXXDataType {
|
||||||
* @Field()
|
* @Field()
|
||||||
*
|
* [name]: [type];
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
function generateErrorArgs(name: string, args: ErrorArgs) {
|
function generateErrorArgs(name: string, args: ErrorArgs) {
|
||||||
const typeName = `${name}DataType`;
|
const typeName = `${name}DataType`;
|
||||||
const lines = [`@ObjectType()`, `class ${typeName} {`];
|
const lines = [`@ObjectType()`, `class ${typeName} {`];
|
||||||
Object.entries(args).forEach(([arg, fieldArgs]) => {
|
Object.entries(args).forEach(([arg, fieldArgs]) => {
|
||||||
if (typeof fieldArgs === 'object') {
|
lines.push(` @Field() ${arg}!: ${fieldArgs}`);
|
||||||
const subResult = generateErrorArgs(
|
|
||||||
name + 'Field' + capitalize(arg),
|
|
||||||
fieldArgs
|
|
||||||
);
|
|
||||||
lines.unshift(subResult.def);
|
|
||||||
lines.push(
|
|
||||||
` @Field(() => ${subResult.name}) ${arg}!: ${subResult.name};`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
lines.push(` @Field() ${arg}!: ${fieldArgs}`);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
lines.push('}');
|
lines.push('}');
|
||||||
|
|||||||
@@ -15,10 +15,11 @@ export function isNetworkError(error: Error): error is NetworkError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class BackendError extends Error {
|
export class BackendError extends Error {
|
||||||
constructor(
|
get status() {
|
||||||
public readonly originError: UserFriendlyError,
|
return this.originError.status;
|
||||||
public readonly status?: number
|
}
|
||||||
) {
|
|
||||||
|
constructor(public readonly originError: UserFriendlyError) {
|
||||||
super(`Server error: ${originError.message}`);
|
super(`Server error: ${originError.message}`);
|
||||||
this.stack = originError.stack;
|
this.stack = originError.stack;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,10 +78,7 @@ export class FetchService extends Service {
|
|||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new BackendError(
|
throw new BackendError(UserFriendlyError.fromAnyError(reason));
|
||||||
UserFriendlyError.fromAnyError(reason),
|
|
||||||
res.status
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import {
|
import {
|
||||||
gqlFetcherFactory,
|
gqlFetcherFactory,
|
||||||
|
GraphQLError,
|
||||||
type GraphQLQuery,
|
type GraphQLQuery,
|
||||||
type QueryOptions,
|
type QueryOptions,
|
||||||
type QueryResponse,
|
type QueryResponse,
|
||||||
|
UserFriendlyError,
|
||||||
} from '@affine/graphql';
|
} from '@affine/graphql';
|
||||||
import { fromPromise, Service } from '@toeverything/infra';
|
import { fromPromise, Service } from '@toeverything/infra';
|
||||||
import type { Observable } from 'rxjs';
|
import type { Observable } from 'rxjs';
|
||||||
@@ -37,12 +39,21 @@ export class GraphQLService extends Service {
|
|||||||
): Promise<QueryResponse<Query>> => {
|
): Promise<QueryResponse<Query>> => {
|
||||||
try {
|
try {
|
||||||
return await this.rawGql(options);
|
return await this.rawGql(options);
|
||||||
} catch (err) {
|
} catch (anyError) {
|
||||||
if (err instanceof BackendError && err.status === 403) {
|
let error = anyError;
|
||||||
|
|
||||||
|
// NOTE(@forehalo):
|
||||||
|
// GraphQL error is not present by non-200 status code, but by responding `errors` fields in the body
|
||||||
|
// So it will never be `BackendError` originally.
|
||||||
|
if (anyError instanceof GraphQLError) {
|
||||||
|
error = new BackendError(UserFriendlyError.fromAnyError(anyError));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error instanceof BackendError && error.status === 403) {
|
||||||
this.framework.get(AuthService).session.revalidate();
|
this.framework.get(AuthService).session.revalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw err;
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
import { readdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
||||||
import { join, parse } from 'node:path';
|
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
|
|
||||||
import { runCli } from '@magic-works/i18n-codegen';
|
|
||||||
|
|
||||||
const isDev = process.argv.includes('--dev');
|
|
||||||
|
|
||||||
const pkgRoot = fileURLToPath(new URL('./', import.meta.url));
|
|
||||||
|
|
||||||
function calcCompletenesses() {
|
|
||||||
const resourcesDir = join(pkgRoot, 'src', 'resources');
|
|
||||||
|
|
||||||
const langs = readdirSync(resourcesDir)
|
|
||||||
.filter(file => file.endsWith('.json'))
|
|
||||||
.reduce((langs, file) => {
|
|
||||||
const filePath = `${resourcesDir}/${file}`;
|
|
||||||
const fileContent = JSON.parse(readFileSync(filePath, 'utf-8'));
|
|
||||||
langs[parse(file).name] = fileContent;
|
|
||||||
return langs;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
const base = Object.keys(langs.en).length;
|
|
||||||
|
|
||||||
const completenesses = {};
|
|
||||||
|
|
||||||
for (const key in langs) {
|
|
||||||
const [langPart, variantPart] = key.split('-');
|
|
||||||
|
|
||||||
const completeness = Object.keys(
|
|
||||||
variantPart ? { ...langs[langPart], ...langs[key] } : langs[key]
|
|
||||||
).length;
|
|
||||||
|
|
||||||
completenesses[key] = Math.min(
|
|
||||||
Math.ceil(/* avoid 0% */ (completeness / base) * 100),
|
|
||||||
100
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
writeFileSync(
|
|
||||||
join(pkgRoot, 'src', 'i18n-completenesses.json'),
|
|
||||||
JSON.stringify(completenesses, null, 2) + '\n'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
runCli(
|
|
||||||
{
|
|
||||||
config: fileURLToPath(new URL('./.i18n-codegen.json', import.meta.url)),
|
|
||||||
watch: isDev,
|
|
||||||
},
|
|
||||||
error => {
|
|
||||||
console.error(error);
|
|
||||||
if (!isDev) {
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
calcCompletenesses();
|
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
import { readdirSync, readFileSync, writeFileSync } from 'node:fs';
|
||||||
|
import { parse } from 'node:path';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
|
import { Package } from '@affine-tools/utils/workspace';
|
||||||
|
import { runCli } from '@magic-works/i18n-codegen';
|
||||||
|
|
||||||
|
const isDev = process.argv.includes('--dev');
|
||||||
|
|
||||||
|
const i18nPkg = new Package('@affine/i18n');
|
||||||
|
const resourcesDir = i18nPkg.join('src', 'resources').toString();
|
||||||
|
|
||||||
|
function readResource(lang: string): Record<string, string> {
|
||||||
|
const filePath = `${resourcesDir}/${lang}.json`;
|
||||||
|
const fileContent = JSON.parse(readFileSync(filePath, 'utf-8'));
|
||||||
|
return fileContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeResource(lang: string, resource: Record<string, string>) {
|
||||||
|
const filePath = `${resourcesDir}/${lang}.json`;
|
||||||
|
writeFileSync(filePath, JSON.stringify(resource, null, 2) + '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
function calcCompletenesses() {
|
||||||
|
const langs = readdirSync(resourcesDir)
|
||||||
|
.filter(file => file.endsWith('.json'))
|
||||||
|
.reduce(
|
||||||
|
(langs, file) => {
|
||||||
|
const lang = parse(file).name;
|
||||||
|
langs[lang] = readResource(lang);
|
||||||
|
return langs;
|
||||||
|
},
|
||||||
|
{} as Record<string, Record<string, string>>
|
||||||
|
);
|
||||||
|
|
||||||
|
const base = Object.keys(langs.en).length;
|
||||||
|
|
||||||
|
const completenesses = {};
|
||||||
|
|
||||||
|
for (const key in langs) {
|
||||||
|
const [langPart, variantPart] = key.split('-');
|
||||||
|
|
||||||
|
const completeness = Object.keys(
|
||||||
|
variantPart ? { ...langs[langPart], ...langs[key] } : langs[key]
|
||||||
|
).length;
|
||||||
|
|
||||||
|
completenesses[key] = Math.min(
|
||||||
|
Math.ceil(/* avoid 0% */ (completeness / base) * 100),
|
||||||
|
100
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
writeFileSync(
|
||||||
|
i18nPkg.join('src', 'i18n-completenesses.json').toString(),
|
||||||
|
JSON.stringify(completenesses, null, 2) + '\n'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function i18nnext() {
|
||||||
|
runCli(
|
||||||
|
{
|
||||||
|
config: fileURLToPath(new URL('./.i18n-codegen.json', import.meta.url)),
|
||||||
|
watch: isDev,
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
console.error(error);
|
||||||
|
if (!isDev) {
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function appendErrorI18n() {
|
||||||
|
const server = new Package('@affine/server');
|
||||||
|
const defFilePath = server.srcPath.join('base/error/def.ts');
|
||||||
|
|
||||||
|
if (!defFilePath.exists()) {
|
||||||
|
throw new Error(
|
||||||
|
`Can not find Server I18n error definition file. It's not placed at [${defFilePath.relativePath}].`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { USER_FRIENDLY_ERRORS } = await import(
|
||||||
|
defFilePath.toFileUrl().toString()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!USER_FRIENDLY_ERRORS) {
|
||||||
|
throw new Error(
|
||||||
|
`Can not find Server I18n error definition file. It's not placed at [${defFilePath.relativePath}] with name [USER_FRIENDLY_ERRORS].`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const en = readResource('en');
|
||||||
|
|
||||||
|
Object.keys(en).forEach(key => {
|
||||||
|
if (key.startsWith('error.')) {
|
||||||
|
delete en[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const key in USER_FRIENDLY_ERRORS) {
|
||||||
|
const def = USER_FRIENDLY_ERRORS[key] as {
|
||||||
|
type: string;
|
||||||
|
args?: Record<string, any>;
|
||||||
|
message: string | ((args: any) => string);
|
||||||
|
};
|
||||||
|
|
||||||
|
en[`error.${key.toUpperCase()}`] =
|
||||||
|
typeof def.message === 'string'
|
||||||
|
? def.message
|
||||||
|
: def.message(
|
||||||
|
Object.keys(def.args ?? {}).reduce(
|
||||||
|
(args, key) => {
|
||||||
|
args[key] = `{{${key}}}`;
|
||||||
|
return args;
|
||||||
|
},
|
||||||
|
{} as Record<string, string>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
writeResource('en', en);
|
||||||
|
}
|
||||||
|
|
||||||
|
await appendErrorI18n();
|
||||||
|
i18nnext();
|
||||||
|
calcCompletenesses();
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@affine/i18n",
|
"name": "@affine/i18n",
|
||||||
|
"version": "0.19.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"private": true,
|
"private": true,
|
||||||
@@ -8,8 +9,8 @@
|
|||||||
".": "./src/index.ts"
|
".": "./src/index.ts"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "node build.mjs",
|
"build": "r build.ts",
|
||||||
"dev": "node build.mjs --dev"
|
"dev": "r build.ts --dev"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -26,8 +27,9 @@
|
|||||||
"undici": "^7.1.0"
|
"undici": "^7.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@affine-tools/cli": "workspace:*",
|
||||||
|
"@affine-tools/utils": "workspace:*",
|
||||||
"glob": "^11.0.0",
|
"glob": "^11.0.0",
|
||||||
"vitest": "3.0.5"
|
"vitest": "3.0.5"
|
||||||
},
|
}
|
||||||
"version": "0.19.0"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
{
|
{
|
||||||
"ar": 98,
|
"ar": 92,
|
||||||
"ca": 5,
|
"ca": 5,
|
||||||
"da": 5,
|
"da": 5,
|
||||||
"de": 98,
|
"de": 92,
|
||||||
"el-GR": 98,
|
"el-GR": 92,
|
||||||
"en": 100,
|
"en": 100,
|
||||||
"es-AR": 98,
|
"es-AR": 92,
|
||||||
"es-CL": 100,
|
"es-CL": 94,
|
||||||
"es": 98,
|
"es": 92,
|
||||||
"fa": 98,
|
"fa": 92,
|
||||||
"fr": 98,
|
"fr": 92,
|
||||||
"hi": 2,
|
"hi": 2,
|
||||||
"it-IT": 98,
|
"it-IT": 92,
|
||||||
"it": 1,
|
"it": 1,
|
||||||
"ja": 98,
|
"ja": 92,
|
||||||
"ko": 71,
|
"ko": 67,
|
||||||
"pl": 98,
|
"pl": 92,
|
||||||
"pt-BR": 98,
|
"pt-BR": 92,
|
||||||
"ru": 98,
|
"ru": 92,
|
||||||
"sv-SE": 98,
|
"sv-SE": 92,
|
||||||
"uk": 98,
|
"uk": 92,
|
||||||
"ur": 2,
|
"ur": 2,
|
||||||
"zh-Hans": 98,
|
"zh-Hans": 92,
|
||||||
"zh-Hant": 98
|
"zh-Hant": 92
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5361,6 +5361,14 @@ export function useAFFiNEI18N(): {
|
|||||||
* `Once enabled, the header of page block will be displayed.`
|
* `Once enabled, the header of page block will be displayed.`
|
||||||
*/
|
*/
|
||||||
["com.affine.settings.workspace.experimental-features.enable-page-block-header.description"](): string;
|
["com.affine.settings.workspace.experimental-features.enable-page-block-header.description"](): string;
|
||||||
|
/**
|
||||||
|
* `Editor RTL`
|
||||||
|
*/
|
||||||
|
["com.affine.settings.workspace.experimental-features.enable-editor-rtl.name"](): string;
|
||||||
|
/**
|
||||||
|
* `Once enabled, the editor will be displayed in RTL mode.`
|
||||||
|
*/
|
||||||
|
["com.affine.settings.workspace.experimental-features.enable-editor-rtl.description"](): string;
|
||||||
/**
|
/**
|
||||||
* `Only an owner can edit the workspace avatar and name. Changes will be shown for everyone.`
|
* `Only an owner can edit the workspace avatar and name. Changes will be shown for everyone.`
|
||||||
*/
|
*/
|
||||||
@@ -5370,7 +5378,7 @@ export function useAFFiNEI18N(): {
|
|||||||
*/
|
*/
|
||||||
["com.affine.settings.workspace.preferences"](): string;
|
["com.affine.settings.workspace.preferences"](): string;
|
||||||
/**
|
/**
|
||||||
* `Team's Team's Billing`
|
* `Team's Billing`
|
||||||
*/
|
*/
|
||||||
["com.affine.settings.workspace.billing"](): string;
|
["com.affine.settings.workspace.billing"](): string;
|
||||||
/**
|
/**
|
||||||
@@ -5550,7 +5558,7 @@ export function useAFFiNEI18N(): {
|
|||||||
*/
|
*/
|
||||||
["com.affine.settings.workspace.backup.import.success.action"](): string;
|
["com.affine.settings.workspace.backup.import.success.action"](): string;
|
||||||
/**
|
/**
|
||||||
* `Deleted {{date}} at {{time}}`
|
* `Deleted on {{date}} at {{time}}`
|
||||||
*/
|
*/
|
||||||
["com.affine.settings.workspace.backup.delete-at"](options: Readonly<{
|
["com.affine.settings.workspace.backup.delete-at"](options: Readonly<{
|
||||||
date: string;
|
date: string;
|
||||||
@@ -6662,6 +6670,437 @@ export function useAFFiNEI18N(): {
|
|||||||
* `Remove template`
|
* `Remove template`
|
||||||
*/
|
*/
|
||||||
["com.affine.settings.workspace.template.remove"](): string;
|
["com.affine.settings.workspace.template.remove"](): string;
|
||||||
|
/**
|
||||||
|
* `Unused blobs`
|
||||||
|
*/
|
||||||
|
["com.affine.settings.workspace.storage.unused-blobs"](): string;
|
||||||
|
/**
|
||||||
|
* `No unused blobs`
|
||||||
|
*/
|
||||||
|
["com.affine.settings.workspace.storage.unused-blobs.empty"](): string;
|
||||||
|
/**
|
||||||
|
* `Selected`
|
||||||
|
*/
|
||||||
|
["com.affine.settings.workspace.storage.unused-blobs.selected"](): string;
|
||||||
|
/**
|
||||||
|
* `Delete blob files`
|
||||||
|
*/
|
||||||
|
["com.affine.settings.workspace.storage.unused-blobs.delete.title"](): string;
|
||||||
|
/**
|
||||||
|
* `Are you sure you want to delete these blob files? This action cannot be undone. Make sure you no longer need them before proceeding.`
|
||||||
|
*/
|
||||||
|
["com.affine.settings.workspace.storage.unused-blobs.delete.warning"](): string;
|
||||||
|
/**
|
||||||
|
* `An internal error occurred.`
|
||||||
|
*/
|
||||||
|
["error.INTERNAL_SERVER_ERROR"](): string;
|
||||||
|
/**
|
||||||
|
* `Too many requests.`
|
||||||
|
*/
|
||||||
|
["error.TOO_MANY_REQUEST"](): string;
|
||||||
|
/**
|
||||||
|
* `Resource not found.`
|
||||||
|
*/
|
||||||
|
["error.NOT_FOUND"](): string;
|
||||||
|
/**
|
||||||
|
* `Query is too long, max length is {{max}}.`
|
||||||
|
*/
|
||||||
|
["error.QUERY_TOO_LONG"](options: {
|
||||||
|
readonly max: string;
|
||||||
|
}): string;
|
||||||
|
/**
|
||||||
|
* `User not found.`
|
||||||
|
*/
|
||||||
|
["error.USER_NOT_FOUND"](): string;
|
||||||
|
/**
|
||||||
|
* `User avatar not found.`
|
||||||
|
*/
|
||||||
|
["error.USER_AVATAR_NOT_FOUND"](): string;
|
||||||
|
/**
|
||||||
|
* `This email has already been registered.`
|
||||||
|
*/
|
||||||
|
["error.EMAIL_ALREADY_USED"](): string;
|
||||||
|
/**
|
||||||
|
* `You are trying to update your account email to the same as the old one.`
|
||||||
|
*/
|
||||||
|
["error.SAME_EMAIL_PROVIDED"](): string;
|
||||||
|
/**
|
||||||
|
* `Wrong user email or password: {{email}}`
|
||||||
|
*/
|
||||||
|
["error.WRONG_SIGN_IN_CREDENTIALS"](options: {
|
||||||
|
readonly email: string;
|
||||||
|
}): string;
|
||||||
|
/**
|
||||||
|
* `Unknown authentication provider {{name}}.`
|
||||||
|
*/
|
||||||
|
["error.UNKNOWN_OAUTH_PROVIDER"](options: {
|
||||||
|
readonly name: string;
|
||||||
|
}): string;
|
||||||
|
/**
|
||||||
|
* `OAuth state expired, please try again.`
|
||||||
|
*/
|
||||||
|
["error.OAUTH_STATE_EXPIRED"](): string;
|
||||||
|
/**
|
||||||
|
* `Invalid callback state parameter.`
|
||||||
|
*/
|
||||||
|
["error.INVALID_OAUTH_CALLBACK_STATE"](): string;
|
||||||
|
/**
|
||||||
|
* `Missing query parameter `{{name}}`.`
|
||||||
|
*/
|
||||||
|
["error.MISSING_OAUTH_QUERY_PARAMETER"](options: {
|
||||||
|
readonly name: string;
|
||||||
|
}): string;
|
||||||
|
/**
|
||||||
|
* `The third-party account has already been connected to another user.`
|
||||||
|
*/
|
||||||
|
["error.OAUTH_ACCOUNT_ALREADY_CONNECTED"](): string;
|
||||||
|
/**
|
||||||
|
* `An invalid email provided: {{email}}`
|
||||||
|
*/
|
||||||
|
["error.INVALID_EMAIL"](options: {
|
||||||
|
readonly email: string;
|
||||||
|
}): string;
|
||||||
|
/**
|
||||||
|
* `Password must be between {{min}} and {{max}} characters`
|
||||||
|
*/
|
||||||
|
["error.INVALID_PASSWORD_LENGTH"](options: Readonly<{
|
||||||
|
min: string;
|
||||||
|
max: string;
|
||||||
|
}>): string;
|
||||||
|
/**
|
||||||
|
* `Password is required.`
|
||||||
|
*/
|
||||||
|
["error.PASSWORD_REQUIRED"](): string;
|
||||||
|
/**
|
||||||
|
* `You are trying to sign in by a different method than you signed up with.`
|
||||||
|
*/
|
||||||
|
["error.WRONG_SIGN_IN_METHOD"](): string;
|
||||||
|
/**
|
||||||
|
* `You don't have early access permission. Visit https://community.affine.pro/c/insider-general/ for more information.`
|
||||||
|
*/
|
||||||
|
["error.EARLY_ACCESS_REQUIRED"](): string;
|
||||||
|
/**
|
||||||
|
* `You are not allowed to sign up.`
|
||||||
|
*/
|
||||||
|
["error.SIGN_UP_FORBIDDEN"](): string;
|
||||||
|
/**
|
||||||
|
* `The email token provided is not found.`
|
||||||
|
*/
|
||||||
|
["error.EMAIL_TOKEN_NOT_FOUND"](): string;
|
||||||
|
/**
|
||||||
|
* `An invalid email token provided.`
|
||||||
|
*/
|
||||||
|
["error.INVALID_EMAIL_TOKEN"](): string;
|
||||||
|
/**
|
||||||
|
* `The link has expired.`
|
||||||
|
*/
|
||||||
|
["error.LINK_EXPIRED"](): string;
|
||||||
|
/**
|
||||||
|
* `You must sign in first to access this resource.`
|
||||||
|
*/
|
||||||
|
["error.AUTHENTICATION_REQUIRED"](): string;
|
||||||
|
/**
|
||||||
|
* `You are not allowed to perform this action.`
|
||||||
|
*/
|
||||||
|
["error.ACTION_FORBIDDEN"](): string;
|
||||||
|
/**
|
||||||
|
* `You do not have permission to access this resource.`
|
||||||
|
*/
|
||||||
|
["error.ACCESS_DENIED"](): string;
|
||||||
|
/**
|
||||||
|
* `You must verify your email before accessing this resource.`
|
||||||
|
*/
|
||||||
|
["error.EMAIL_VERIFICATION_REQUIRED"](): string;
|
||||||
|
/**
|
||||||
|
* `Space {{spaceId}} not found.`
|
||||||
|
*/
|
||||||
|
["error.SPACE_NOT_FOUND"](options: {
|
||||||
|
readonly spaceId: string;
|
||||||
|
}): string;
|
||||||
|
/**
|
||||||
|
* `Member not found in Space {{spaceId}}.`
|
||||||
|
*/
|
||||||
|
["error.MEMBER_NOT_FOUND_IN_SPACE"](options: {
|
||||||
|
readonly spaceId: string;
|
||||||
|
}): string;
|
||||||
|
/**
|
||||||
|
* `You should join in Space {{spaceId}} before broadcasting messages.`
|
||||||
|
*/
|
||||||
|
["error.NOT_IN_SPACE"](options: {
|
||||||
|
readonly spaceId: string;
|
||||||
|
}): string;
|
||||||
|
/**
|
||||||
|
* `You have already joined in Space {{spaceId}}.`
|
||||||
|
*/
|
||||||
|
["error.ALREADY_IN_SPACE"](options: {
|
||||||
|
readonly spaceId: string;
|
||||||
|
}): string;
|
||||||
|
/**
|
||||||
|
* `You do not have permission to access Space {{spaceId}}.`
|
||||||
|
*/
|
||||||
|
["error.SPACE_ACCESS_DENIED"](options: {
|
||||||
|
readonly spaceId: string;
|
||||||
|
}): string;
|
||||||
|
/**
|
||||||
|
* `Owner of Space {{spaceId}} not found.`
|
||||||
|
*/
|
||||||
|
["error.SPACE_OWNER_NOT_FOUND"](options: {
|
||||||
|
readonly spaceId: string;
|
||||||
|
}): string;
|
||||||
|
/**
|
||||||
|
* `Doc {{docId}} under Space {{spaceId}} not found.`
|
||||||
|
*/
|
||||||
|
["error.DOC_NOT_FOUND"](options: Readonly<{
|
||||||
|
docId: string;
|
||||||
|
spaceId: string;
|
||||||
|
}>): string;
|
||||||
|
/**
|
||||||
|
* `You do not have permission to access doc {{docId}} under Space {{spaceId}}.`
|
||||||
|
*/
|
||||||
|
["error.DOC_ACCESS_DENIED"](options: Readonly<{
|
||||||
|
docId: string;
|
||||||
|
spaceId: string;
|
||||||
|
}>): string;
|
||||||
|
/**
|
||||||
|
* `Your client with version {{version}} is rejected by remote sync server. Please upgrade to {{serverVersion}}.`
|
||||||
|
*/
|
||||||
|
["error.VERSION_REJECTED"](options: Readonly<{
|
||||||
|
version: string;
|
||||||
|
serverVersion: string;
|
||||||
|
}>): string;
|
||||||
|
/**
|
||||||
|
* `Invalid doc history timestamp provided.`
|
||||||
|
*/
|
||||||
|
["error.INVALID_HISTORY_TIMESTAMP"](): string;
|
||||||
|
/**
|
||||||
|
* `History of {{docId}} at {{timestamp}} under Space {{spaceId}}.`
|
||||||
|
*/
|
||||||
|
["error.DOC_HISTORY_NOT_FOUND"](options: Readonly<{
|
||||||
|
docId: string;
|
||||||
|
timestamp: string;
|
||||||
|
spaceId: string;
|
||||||
|
}>): string;
|
||||||
|
/**
|
||||||
|
* `Blob {{blobId}} not found in Space {{spaceId}}.`
|
||||||
|
*/
|
||||||
|
["error.BLOB_NOT_FOUND"](options: Readonly<{
|
||||||
|
blobId: string;
|
||||||
|
spaceId: string;
|
||||||
|
}>): string;
|
||||||
|
/**
|
||||||
|
* `Expected to publish a page, not a Space.`
|
||||||
|
*/
|
||||||
|
["error.EXPECT_TO_PUBLISH_PAGE"](): string;
|
||||||
|
/**
|
||||||
|
* `Expected to revoke a public page, not a Space.`
|
||||||
|
*/
|
||||||
|
["error.EXPECT_TO_REVOKE_PUBLIC_PAGE"](): string;
|
||||||
|
/**
|
||||||
|
* `Page is not public.`
|
||||||
|
*/
|
||||||
|
["error.PAGE_IS_NOT_PUBLIC"](): string;
|
||||||
|
/**
|
||||||
|
* `Failed to store doc updates.`
|
||||||
|
*/
|
||||||
|
["error.FAILED_TO_SAVE_UPDATES"](): string;
|
||||||
|
/**
|
||||||
|
* `Failed to store doc snapshot.`
|
||||||
|
*/
|
||||||
|
["error.FAILED_TO_UPSERT_SNAPSHOT"](): string;
|
||||||
|
/**
|
||||||
|
* `Unsupported subscription plan: {{plan}}.`
|
||||||
|
*/
|
||||||
|
["error.UNSUPPORTED_SUBSCRIPTION_PLAN"](options: {
|
||||||
|
readonly plan: string;
|
||||||
|
}): string;
|
||||||
|
/**
|
||||||
|
* `Failed to create checkout session.`
|
||||||
|
*/
|
||||||
|
["error.FAILED_TO_CHECKOUT"](): string;
|
||||||
|
/**
|
||||||
|
* `Invalid checkout parameters provided.`
|
||||||
|
*/
|
||||||
|
["error.INVALID_CHECKOUT_PARAMETERS"](): string;
|
||||||
|
/**
|
||||||
|
* `You have already subscribed to the {{plan}} plan.`
|
||||||
|
*/
|
||||||
|
["error.SUBSCRIPTION_ALREADY_EXISTS"](options: {
|
||||||
|
readonly plan: string;
|
||||||
|
}): string;
|
||||||
|
/**
|
||||||
|
* `Invalid subscription parameters provided.`
|
||||||
|
*/
|
||||||
|
["error.INVALID_SUBSCRIPTION_PARAMETERS"](): string;
|
||||||
|
/**
|
||||||
|
* `You didn't subscribe to the {{plan}} plan.`
|
||||||
|
*/
|
||||||
|
["error.SUBSCRIPTION_NOT_EXISTS"](options: {
|
||||||
|
readonly plan: string;
|
||||||
|
}): string;
|
||||||
|
/**
|
||||||
|
* `Your subscription has already been canceled.`
|
||||||
|
*/
|
||||||
|
["error.SUBSCRIPTION_HAS_BEEN_CANCELED"](): string;
|
||||||
|
/**
|
||||||
|
* `Your subscription has not been canceled.`
|
||||||
|
*/
|
||||||
|
["error.SUBSCRIPTION_HAS_NOT_BEEN_CANCELED"](): string;
|
||||||
|
/**
|
||||||
|
* `Your subscription has expired.`
|
||||||
|
*/
|
||||||
|
["error.SUBSCRIPTION_EXPIRED"](): string;
|
||||||
|
/**
|
||||||
|
* `Your subscription has already been in {{recurring}} recurring state.`
|
||||||
|
*/
|
||||||
|
["error.SAME_SUBSCRIPTION_RECURRING"](options: {
|
||||||
|
readonly recurring: string;
|
||||||
|
}): string;
|
||||||
|
/**
|
||||||
|
* `Failed to create customer portal session.`
|
||||||
|
*/
|
||||||
|
["error.CUSTOMER_PORTAL_CREATE_FAILED"](): string;
|
||||||
|
/**
|
||||||
|
* `You are trying to access a unknown subscription plan.`
|
||||||
|
*/
|
||||||
|
["error.SUBSCRIPTION_PLAN_NOT_FOUND"](): string;
|
||||||
|
/**
|
||||||
|
* `You cannot update an onetime payment subscription.`
|
||||||
|
*/
|
||||||
|
["error.CANT_UPDATE_ONETIME_PAYMENT_SUBSCRIPTION"](): string;
|
||||||
|
/**
|
||||||
|
* `A workspace is required to checkout for team subscription.`
|
||||||
|
*/
|
||||||
|
["error.WORKSPACE_ID_REQUIRED_FOR_TEAM_SUBSCRIPTION"](): string;
|
||||||
|
/**
|
||||||
|
* `Workspace id is required to update team subscription.`
|
||||||
|
*/
|
||||||
|
["error.WORKSPACE_ID_REQUIRED_TO_UPDATE_TEAM_SUBSCRIPTION"](): string;
|
||||||
|
/**
|
||||||
|
* `Copilot session not found.`
|
||||||
|
*/
|
||||||
|
["error.COPILOT_SESSION_NOT_FOUND"](): string;
|
||||||
|
/**
|
||||||
|
* `Copilot session has been deleted.`
|
||||||
|
*/
|
||||||
|
["error.COPILOT_SESSION_DELETED"](): string;
|
||||||
|
/**
|
||||||
|
* `No copilot provider available.`
|
||||||
|
*/
|
||||||
|
["error.NO_COPILOT_PROVIDER_AVAILABLE"](): string;
|
||||||
|
/**
|
||||||
|
* `Failed to generate text.`
|
||||||
|
*/
|
||||||
|
["error.COPILOT_FAILED_TO_GENERATE_TEXT"](): string;
|
||||||
|
/**
|
||||||
|
* `Failed to create chat message.`
|
||||||
|
*/
|
||||||
|
["error.COPILOT_FAILED_TO_CREATE_MESSAGE"](): string;
|
||||||
|
/**
|
||||||
|
* `Unsplash is not configured.`
|
||||||
|
*/
|
||||||
|
["error.UNSPLASH_IS_NOT_CONFIGURED"](): string;
|
||||||
|
/**
|
||||||
|
* `Action has been taken, no more messages allowed.`
|
||||||
|
*/
|
||||||
|
["error.COPILOT_ACTION_TAKEN"](): string;
|
||||||
|
/**
|
||||||
|
* `Copilot message {{messageId}} not found.`
|
||||||
|
*/
|
||||||
|
["error.COPILOT_MESSAGE_NOT_FOUND"](options: {
|
||||||
|
readonly messageId: string;
|
||||||
|
}): string;
|
||||||
|
/**
|
||||||
|
* `Copilot prompt {{name}} not found.`
|
||||||
|
*/
|
||||||
|
["error.COPILOT_PROMPT_NOT_FOUND"](options: {
|
||||||
|
readonly name: string;
|
||||||
|
}): string;
|
||||||
|
/**
|
||||||
|
* `Copilot prompt is invalid.`
|
||||||
|
*/
|
||||||
|
["error.COPILOT_PROMPT_INVALID"](): string;
|
||||||
|
/**
|
||||||
|
* `Provider {{provider}} failed with {{kind}} error: {{message}}`
|
||||||
|
*/
|
||||||
|
["error.COPILOT_PROVIDER_SIDE_ERROR"](options: Readonly<{
|
||||||
|
provider: string;
|
||||||
|
kind: string;
|
||||||
|
message: string;
|
||||||
|
}>): string;
|
||||||
|
/**
|
||||||
|
* `You have exceeded your blob storage quota.`
|
||||||
|
*/
|
||||||
|
["error.BLOB_QUOTA_EXCEEDED"](): string;
|
||||||
|
/**
|
||||||
|
* `You have exceeded your workspace member quota.`
|
||||||
|
*/
|
||||||
|
["error.MEMBER_QUOTA_EXCEEDED"](): string;
|
||||||
|
/**
|
||||||
|
* `You have reached the limit of actions in this workspace, please upgrade your plan.`
|
||||||
|
*/
|
||||||
|
["error.COPILOT_QUOTA_EXCEEDED"](): string;
|
||||||
|
/**
|
||||||
|
* `Runtime config {{key}} not found.`
|
||||||
|
*/
|
||||||
|
["error.RUNTIME_CONFIG_NOT_FOUND"](options: {
|
||||||
|
readonly key: string;
|
||||||
|
}): string;
|
||||||
|
/**
|
||||||
|
* `Invalid runtime config type for '{{key}}', want '{{want}}', but get {{get}}.`
|
||||||
|
*/
|
||||||
|
["error.INVALID_RUNTIME_CONFIG_TYPE"](options: Readonly<{
|
||||||
|
key: string;
|
||||||
|
want: string;
|
||||||
|
get: string;
|
||||||
|
}>): string;
|
||||||
|
/**
|
||||||
|
* `Mailer service is not configured.`
|
||||||
|
*/
|
||||||
|
["error.MAILER_SERVICE_IS_NOT_CONFIGURED"](): string;
|
||||||
|
/**
|
||||||
|
* `Cannot delete all admin accounts.`
|
||||||
|
*/
|
||||||
|
["error.CANNOT_DELETE_ALL_ADMIN_ACCOUNT"](): string;
|
||||||
|
/**
|
||||||
|
* `Cannot delete own account.`
|
||||||
|
*/
|
||||||
|
["error.CANNOT_DELETE_OWN_ACCOUNT"](): string;
|
||||||
|
/**
|
||||||
|
* `Captcha verification failed.`
|
||||||
|
*/
|
||||||
|
["error.CAPTCHA_VERIFICATION_FAILED"](): string;
|
||||||
|
/**
|
||||||
|
* `Invalid session id to generate license key.`
|
||||||
|
*/
|
||||||
|
["error.INVALID_LICENSE_SESSION_ID"](): string;
|
||||||
|
/**
|
||||||
|
* `License key has been revealed. Please check your mail box of the one provided during checkout.`
|
||||||
|
*/
|
||||||
|
["error.LICENSE_REVEALED"](): string;
|
||||||
|
/**
|
||||||
|
* `Workspace already has a license applied.`
|
||||||
|
*/
|
||||||
|
["error.WORKSPACE_LICENSE_ALREADY_EXISTS"](): string;
|
||||||
|
/**
|
||||||
|
* `License not found.`
|
||||||
|
*/
|
||||||
|
["error.LICENSE_NOT_FOUND"](): string;
|
||||||
|
/**
|
||||||
|
* `Invalid license to activate.`
|
||||||
|
*/
|
||||||
|
["error.INVALID_LICENSE_TO_ACTIVATE"](): string;
|
||||||
|
/**
|
||||||
|
* `Invalid license update params. {{reason}}`
|
||||||
|
*/
|
||||||
|
["error.INVALID_LICENSE_UPDATE_PARAMS"](options: {
|
||||||
|
readonly reason: string;
|
||||||
|
}): string;
|
||||||
|
/**
|
||||||
|
* `You cannot downgrade the workspace from team workspace because there are more than {{limit}} members that are currently active.`
|
||||||
|
*/
|
||||||
|
["error.WORKSPACE_MEMBERS_EXCEED_LIMIT_TO_DOWNGRADE"](options: {
|
||||||
|
readonly limit: string;
|
||||||
|
}): string;
|
||||||
} { const { t } = useTranslation(); return useMemo(() => createProxy((key) => t.bind(null, key)), [t]); }
|
} { const { t } = useTranslation(); return useMemo(() => createProxy((key) => t.bind(null, key)), [t]); }
|
||||||
function createComponent(i18nKey: string) {
|
function createComponent(i18nKey: string) {
|
||||||
return (props) => createElement(Trans, { i18nKey, shouldUnescape: true, ...props });
|
return (props) => createElement(Trans, { i18nKey, shouldUnescape: true, ...props });
|
||||||
|
|||||||
@@ -1666,5 +1666,91 @@
|
|||||||
"com.affine.settings.workspace.storage.unused-blobs.empty": "No unused blobs",
|
"com.affine.settings.workspace.storage.unused-blobs.empty": "No unused blobs",
|
||||||
"com.affine.settings.workspace.storage.unused-blobs.selected": "Selected",
|
"com.affine.settings.workspace.storage.unused-blobs.selected": "Selected",
|
||||||
"com.affine.settings.workspace.storage.unused-blobs.delete.title": "Delete blob files",
|
"com.affine.settings.workspace.storage.unused-blobs.delete.title": "Delete blob files",
|
||||||
"com.affine.settings.workspace.storage.unused-blobs.delete.warning": "Are you sure you want to delete these blob files? This action cannot be undone. Make sure you no longer need them before proceeding."
|
"com.affine.settings.workspace.storage.unused-blobs.delete.warning": "Are you sure you want to delete these blob files? This action cannot be undone. Make sure you no longer need them before proceeding.",
|
||||||
|
"error.INTERNAL_SERVER_ERROR": "An internal error occurred.",
|
||||||
|
"error.TOO_MANY_REQUEST": "Too many requests.",
|
||||||
|
"error.NOT_FOUND": "Resource not found.",
|
||||||
|
"error.QUERY_TOO_LONG": "Query is too long, max length is {{max}}.",
|
||||||
|
"error.USER_NOT_FOUND": "User not found.",
|
||||||
|
"error.USER_AVATAR_NOT_FOUND": "User avatar not found.",
|
||||||
|
"error.EMAIL_ALREADY_USED": "This email has already been registered.",
|
||||||
|
"error.SAME_EMAIL_PROVIDED": "You are trying to update your account email to the same as the old one.",
|
||||||
|
"error.WRONG_SIGN_IN_CREDENTIALS": "Wrong user email or password: {{email}}",
|
||||||
|
"error.UNKNOWN_OAUTH_PROVIDER": "Unknown authentication provider {{name}}.",
|
||||||
|
"error.OAUTH_STATE_EXPIRED": "OAuth state expired, please try again.",
|
||||||
|
"error.INVALID_OAUTH_CALLBACK_STATE": "Invalid callback state parameter.",
|
||||||
|
"error.MISSING_OAUTH_QUERY_PARAMETER": "Missing query parameter `{{name}}`.",
|
||||||
|
"error.OAUTH_ACCOUNT_ALREADY_CONNECTED": "The third-party account has already been connected to another user.",
|
||||||
|
"error.INVALID_EMAIL": "An invalid email provided: {{email}}",
|
||||||
|
"error.INVALID_PASSWORD_LENGTH": "Password must be between {{min}} and {{max}} characters",
|
||||||
|
"error.PASSWORD_REQUIRED": "Password is required.",
|
||||||
|
"error.WRONG_SIGN_IN_METHOD": "You are trying to sign in by a different method than you signed up with.",
|
||||||
|
"error.EARLY_ACCESS_REQUIRED": "You don't have early access permission. Visit https://community.affine.pro/c/insider-general/ for more information.",
|
||||||
|
"error.SIGN_UP_FORBIDDEN": "You are not allowed to sign up.",
|
||||||
|
"error.EMAIL_TOKEN_NOT_FOUND": "The email token provided is not found.",
|
||||||
|
"error.INVALID_EMAIL_TOKEN": "An invalid email token provided.",
|
||||||
|
"error.LINK_EXPIRED": "The link has expired.",
|
||||||
|
"error.AUTHENTICATION_REQUIRED": "You must sign in first to access this resource.",
|
||||||
|
"error.ACTION_FORBIDDEN": "You are not allowed to perform this action.",
|
||||||
|
"error.ACCESS_DENIED": "You do not have permission to access this resource.",
|
||||||
|
"error.EMAIL_VERIFICATION_REQUIRED": "You must verify your email before accessing this resource.",
|
||||||
|
"error.SPACE_NOT_FOUND": "Space {{spaceId}} not found.",
|
||||||
|
"error.MEMBER_NOT_FOUND_IN_SPACE": "Member not found in Space {{spaceId}}.",
|
||||||
|
"error.NOT_IN_SPACE": "You should join in Space {{spaceId}} before broadcasting messages.",
|
||||||
|
"error.ALREADY_IN_SPACE": "You have already joined in Space {{spaceId}}.",
|
||||||
|
"error.SPACE_ACCESS_DENIED": "You do not have permission to access Space {{spaceId}}.",
|
||||||
|
"error.SPACE_OWNER_NOT_FOUND": "Owner of Space {{spaceId}} not found.",
|
||||||
|
"error.DOC_NOT_FOUND": "Doc {{docId}} under Space {{spaceId}} not found.",
|
||||||
|
"error.DOC_ACCESS_DENIED": "You do not have permission to access doc {{docId}} under Space {{spaceId}}.",
|
||||||
|
"error.VERSION_REJECTED": "Your client with version {{version}} is rejected by remote sync server. Please upgrade to {{serverVersion}}.",
|
||||||
|
"error.INVALID_HISTORY_TIMESTAMP": "Invalid doc history timestamp provided.",
|
||||||
|
"error.DOC_HISTORY_NOT_FOUND": "History of {{docId}} at {{timestamp}} under Space {{spaceId}}.",
|
||||||
|
"error.BLOB_NOT_FOUND": "Blob {{blobId}} not found in Space {{spaceId}}.",
|
||||||
|
"error.EXPECT_TO_PUBLISH_PAGE": "Expected to publish a page, not a Space.",
|
||||||
|
"error.EXPECT_TO_REVOKE_PUBLIC_PAGE": "Expected to revoke a public page, not a Space.",
|
||||||
|
"error.PAGE_IS_NOT_PUBLIC": "Page is not public.",
|
||||||
|
"error.FAILED_TO_SAVE_UPDATES": "Failed to store doc updates.",
|
||||||
|
"error.FAILED_TO_UPSERT_SNAPSHOT": "Failed to store doc snapshot.",
|
||||||
|
"error.UNSUPPORTED_SUBSCRIPTION_PLAN": "Unsupported subscription plan: {{plan}}.",
|
||||||
|
"error.FAILED_TO_CHECKOUT": "Failed to create checkout session.",
|
||||||
|
"error.INVALID_CHECKOUT_PARAMETERS": "Invalid checkout parameters provided.",
|
||||||
|
"error.SUBSCRIPTION_ALREADY_EXISTS": "You have already subscribed to the {{plan}} plan.",
|
||||||
|
"error.INVALID_SUBSCRIPTION_PARAMETERS": "Invalid subscription parameters provided.",
|
||||||
|
"error.SUBSCRIPTION_NOT_EXISTS": "You didn't subscribe to the {{plan}} plan.",
|
||||||
|
"error.SUBSCRIPTION_HAS_BEEN_CANCELED": "Your subscription has already been canceled.",
|
||||||
|
"error.SUBSCRIPTION_HAS_NOT_BEEN_CANCELED": "Your subscription has not been canceled.",
|
||||||
|
"error.SUBSCRIPTION_EXPIRED": "Your subscription has expired.",
|
||||||
|
"error.SAME_SUBSCRIPTION_RECURRING": "Your subscription has already been in {{recurring}} recurring state.",
|
||||||
|
"error.CUSTOMER_PORTAL_CREATE_FAILED": "Failed to create customer portal session.",
|
||||||
|
"error.SUBSCRIPTION_PLAN_NOT_FOUND": "You are trying to access a unknown subscription plan.",
|
||||||
|
"error.CANT_UPDATE_ONETIME_PAYMENT_SUBSCRIPTION": "You cannot update an onetime payment subscription.",
|
||||||
|
"error.WORKSPACE_ID_REQUIRED_FOR_TEAM_SUBSCRIPTION": "A workspace is required to checkout for team subscription.",
|
||||||
|
"error.WORKSPACE_ID_REQUIRED_TO_UPDATE_TEAM_SUBSCRIPTION": "Workspace id is required to update team subscription.",
|
||||||
|
"error.COPILOT_SESSION_NOT_FOUND": "Copilot session not found.",
|
||||||
|
"error.COPILOT_SESSION_DELETED": "Copilot session has been deleted.",
|
||||||
|
"error.NO_COPILOT_PROVIDER_AVAILABLE": "No copilot provider available.",
|
||||||
|
"error.COPILOT_FAILED_TO_GENERATE_TEXT": "Failed to generate text.",
|
||||||
|
"error.COPILOT_FAILED_TO_CREATE_MESSAGE": "Failed to create chat message.",
|
||||||
|
"error.UNSPLASH_IS_NOT_CONFIGURED": "Unsplash is not configured.",
|
||||||
|
"error.COPILOT_ACTION_TAKEN": "Action has been taken, no more messages allowed.",
|
||||||
|
"error.COPILOT_MESSAGE_NOT_FOUND": "Copilot message {{messageId}} not found.",
|
||||||
|
"error.COPILOT_PROMPT_NOT_FOUND": "Copilot prompt {{name}} not found.",
|
||||||
|
"error.COPILOT_PROMPT_INVALID": "Copilot prompt is invalid.",
|
||||||
|
"error.COPILOT_PROVIDER_SIDE_ERROR": "Provider {{provider}} failed with {{kind}} error: {{message}}",
|
||||||
|
"error.BLOB_QUOTA_EXCEEDED": "You have exceeded your blob storage quota.",
|
||||||
|
"error.MEMBER_QUOTA_EXCEEDED": "You have exceeded your workspace member quota.",
|
||||||
|
"error.COPILOT_QUOTA_EXCEEDED": "You have reached the limit of actions in this workspace, please upgrade your plan.",
|
||||||
|
"error.RUNTIME_CONFIG_NOT_FOUND": "Runtime config {{key}} not found.",
|
||||||
|
"error.INVALID_RUNTIME_CONFIG_TYPE": "Invalid runtime config type for '{{key}}', want '{{want}}', but get {{get}}.",
|
||||||
|
"error.MAILER_SERVICE_IS_NOT_CONFIGURED": "Mailer service is not configured.",
|
||||||
|
"error.CANNOT_DELETE_ALL_ADMIN_ACCOUNT": "Cannot delete all admin accounts.",
|
||||||
|
"error.CANNOT_DELETE_OWN_ACCOUNT": "Cannot delete own account.",
|
||||||
|
"error.CAPTCHA_VERIFICATION_FAILED": "Captcha verification failed.",
|
||||||
|
"error.INVALID_LICENSE_SESSION_ID": "Invalid session id to generate license key.",
|
||||||
|
"error.LICENSE_REVEALED": "License key has been revealed. Please check your mail box of the one provided during checkout.",
|
||||||
|
"error.WORKSPACE_LICENSE_ALREADY_EXISTS": "Workspace already has a license applied.",
|
||||||
|
"error.LICENSE_NOT_FOUND": "License not found.",
|
||||||
|
"error.INVALID_LICENSE_TO_ACTIVATE": "Invalid license to activate.",
|
||||||
|
"error.INVALID_LICENSE_UPDATE_PARAMS": "Invalid license update params. {{reason}}",
|
||||||
|
"error.WORKSPACE_MEMBERS_EXCEED_LIMIT_TO_DOWNGRADE": "You cannot downgrade the workspace from team workspace because there are more than {{limit}} members that are currently active."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ const lookups = [];
|
|||||||
*/
|
*/
|
||||||
let scriptLocation;
|
let scriptLocation;
|
||||||
for (const location of fileLocationCandidates) {
|
for (const location of fileLocationCandidates) {
|
||||||
|
if (scriptLocation) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
const fileCandidates = [file, `${file}.js`, `${file}.ts`];
|
const fileCandidates = [file, `${file}.js`, `${file}.ts`];
|
||||||
for (const candidate of fileCandidates) {
|
for (const candidate of fileCandidates) {
|
||||||
const candidateLocation = join(location, candidate);
|
const candidateLocation = join(location, candidate);
|
||||||
|
|||||||
@@ -585,6 +585,8 @@ __metadata:
|
|||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@affine/i18n@workspace:packages/frontend/i18n"
|
resolution: "@affine/i18n@workspace:packages/frontend/i18n"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
"@affine-tools/cli": "workspace:*"
|
||||||
|
"@affine-tools/utils": "workspace:*"
|
||||||
"@affine/debug": "workspace:*"
|
"@affine/debug": "workspace:*"
|
||||||
"@magic-works/i18n-codegen": "npm:^0.6.1"
|
"@magic-works/i18n-codegen": "npm:^0.6.1"
|
||||||
dayjs: "npm:^1.11.13"
|
dayjs: "npm:^1.11.13"
|
||||||
|
|||||||
Reference in New Issue
Block a user