feat(i18n): add Azerbaijani locale

This commit is contained in:
Jamal Ali authored and GitHub committed 2026-09-09 12:30:53 +08:00
1 parent ef1d7ae9c4
commit 3408ddbb65
29 files changed
+9867 -18

No files matched your search

@@ -2,7 +2,7 @@ import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
const source = readFileSync(new URL("../AiAssistant.vue", import.meta.url), "utf8"); const source = readFileSync(new URL("../AiAssistant.vue", import.meta.url), "utf8");
const localePaths = ["en", "es", "it", "ja", "ko", "pt-BR", "tr", "zh-CN", "zh-TW"]; const localePaths = ["az", "en", "es", "it", "ja", "ko", "pt-BR", "tr", "zh-CN", "zh-TW"];
describe("AI assistant write confirmation replacement", () => { describe("AI assistant write confirmation replacement", () => {
it("renders a localized confirmation from the backend's semantic event", () => { it("renders a localized confirmation from the backend's semantic event", () => {
@@ -104,7 +104,7 @@ describe("EditorSettingsDialog live preview placement", () => {
it("describes the execute shortcut below the mode selector in every supported locale", () => { it("describes the execute shortcut below the mode selector in every supported locale", () => {
expect(editorSection.indexOf("executeModeDescription")).toBeGreaterThan(editorSection.indexOf("executeModeLabel")); expect(editorSection.indexOf("executeModeDescription")).toBeGreaterThan(editorSection.indexOf("executeModeLabel"));
for (const locale of ["zh-CN", "zh-TW", "en", "es", "it", "ja", "ko", "pt-BR", "tr"]) { for (const locale of ["zh-CN", "zh-TW", "en", "es", "it", "ja", "ko", "pt-BR", "tr", "az"]) {
const source = readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8"); const source = readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8");
expect(source, locale).toContain("executeModeDescription:"); expect(source, locale).toContain("executeModeDescription:");
} }
@@ -115,7 +115,7 @@ describe("EditorSettingsDialog live preview placement", () => {
expect(editorSection).toContain("{{ completionTriggerModeDescription }}"); expect(editorSection).toContain("{{ completionTriggerModeDescription }}");
expect(editorSection).not.toContain('t("settings.completionTriggerModeDescription")'); expect(editorSection).not.toContain('t("settings.completionTriggerModeDescription")');
for (const locale of ["zh-CN", "zh-TW", "en", "es", "it", "ja", "ko", "pt-BR", "tr"]) { for (const locale of ["zh-CN", "zh-TW", "en", "es", "it", "ja", "ko", "pt-BR", "tr", "az"]) {
const source = readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8"); const source = readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8");
for (const key of ["completionTriggerModeManualDescription", "completionTriggerModeRequirePrefixDescription", "completionTriggerModePositionalDescription"]) { for (const key of ["completionTriggerModeManualDescription", "completionTriggerModeRequirePrefixDescription", "completionTriggerModePositionalDescription"]) {
expect(source, `${locale}:${key}`).toContain(`${key}:`); expect(source, `${locale}:${key}`).toContain(`${key}:`);
@@ -174,7 +174,7 @@ describe("EditorSettingsDialog live preview placement", () => {
expect(dataSection.match(/editDataGridFilterEditorView = '(quick|conditions|text)'/g)).toHaveLength(3); expect(dataSection.match(/editDataGridFilterEditorView = '(quick|conditions|text)'/g)).toHaveLength(3);
expect(dataSection).not.toContain('<SelectTrigger id="data-grid-filter-view"'); expect(dataSection).not.toContain('<SelectTrigger id="data-grid-filter-view"');
for (const locale of ["zh-CN", "zh-TW", "en", "es", "it", "ja", "ko", "pt-BR", "tr"]) { for (const locale of ["zh-CN", "zh-TW", "en", "es", "it", "ja", "ko", "pt-BR", "tr", "az"]) {
const source = readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8"); const source = readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8");
for (const key of ["dataGridFilterViewPreview", "dataGridFilterViewPreviewExpand", "dataGridFilterViewPreviewCollapse"]) { for (const key of ["dataGridFilterViewPreview", "dataGridFilterViewPreviewExpand", "dataGridFilterViewPreviewCollapse"]) {
expect(source, `${locale}:${key}`).toContain(`${key}:`); expect(source, `${locale}:${key}`).toContain(`${key}:`);
@@ -215,7 +215,7 @@ describe("EditorSettingsDialog live preview placement", () => {
expect(editorPreview.indexOf('t("settings.previewSyntaxErrorHint")')).toBeGreaterThan(preview); expect(editorPreview.indexOf('t("settings.previewSyntaxErrorHint")')).toBeGreaterThan(preview);
}); });
it.each(["en", "zh-CN", "zh-TW", "es", "pt-BR", "it", "ja", "ko", "tr"])("locale %s translates settings.previewSyntaxErrorHint", (locale) => { it.each(["en", "zh-CN", "zh-TW", "es", "pt-BR", "it", "ja", "ko", "tr", "az"])("locale %s translates settings.previewSyntaxErrorHint", (locale) => {
const localeSource = readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8"); const localeSource = readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8");
expect(localeSource).toMatch(/previewSyntaxErrorHint: ".+"/); expect(localeSource).toMatch(/previewSyntaxErrorHint: ".+"/);
}); });
@@ -5,6 +5,7 @@ import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime"; import relativeTime from "dayjs/plugin/relativeTime";
import "dayjs/locale/zh-cn"; import "dayjs/locale/zh-cn";
import "dayjs/locale/zh-tw"; import "dayjs/locale/zh-tw";
import "dayjs/locale/az";
import "dayjs/locale/es"; import "dayjs/locale/es";
import "dayjs/locale/it"; import "dayjs/locale/it";
import "dayjs/locale/ja"; import "dayjs/locale/ja";
@@ -23,6 +24,7 @@ import MeilisearchTasksPage from "./MeilisearchTasksPage.vue";
dayjs.extend(relativeTime); dayjs.extend(relativeTime);
const DAYJS_LOCALES: Record<string, string> = { const DAYJS_LOCALES: Record<string, string> = {
az: "az",
"zh-CN": "zh-cn", "zh-CN": "zh-cn",
"zh-TW": "zh-tw", "zh-TW": "zh-tw",
"pt-BR": "pt-br", "pt-BR": "pt-br",
@@ -1,4 +1,5 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import az from "../locales/az";
import en from "../locales/en"; import en from "../locales/en";
import es from "../locales/es"; import es from "../locales/es";
import itLocale from "../locales/it"; import itLocale from "../locales/it";
@@ -12,6 +13,7 @@ import zhTW from "../locales/zh-TW";
type Messages = Record<string, unknown>; type Messages = Record<string, unknown>;
const locales: Array<[string, Messages]> = [ const locales: Array<[string, Messages]> = [
["az", az],
["es", es], ["es", es],
["it", itLocale], ["it", itLocale],
["ja", ja], ["ja", ja],
@@ -1,4 +1,5 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import az from "../locales/az";
import en from "../locales/en"; import en from "../locales/en";
import es from "../locales/es"; import es from "../locales/es";
import it_ from "../locales/it"; import it_ from "../locales/it";
@@ -10,6 +11,7 @@ import zhCN from "../locales/zh-CN";
import zhTW from "../locales/zh-TW"; import zhTW from "../locales/zh-TW";
const locales: Array<[string, Record<string, unknown>]> = [ const locales: Array<[string, Record<string, unknown>]> = [
["az", az],
["en", en], ["en", en],
["es", es], ["es", es],
["it", it_], ["it", it_],
+2
View File
@@ -3,6 +3,7 @@ import { describe, expect, it as test } from "vitest";
import { createI18n } from "vue-i18n"; import { createI18n } from "vue-i18n";
import { translateBackendError, type BackendErrorTranslate } from "@/i18n/backend-errors"; import { translateBackendError, type BackendErrorTranslate } from "@/i18n/backend-errors";
import { BackendErrorException, formatError, normalizeBackendError, sanitizeBackendErrorMessage } from "@/lib/backend/errorUtils"; import { BackendErrorException, formatError, normalizeBackendError, sanitizeBackendErrorMessage } from "@/lib/backend/errorUtils";
import az from "@/i18n/locales/az";
import en from "@/i18n/locales/en"; import en from "@/i18n/locales/en";
import es from "@/i18n/locales/es"; import es from "@/i18n/locales/es";
import it from "@/i18n/locales/it"; import it from "@/i18n/locales/it";
@@ -15,6 +16,7 @@ import zhTW from "@/i18n/locales/zh-TW";
import { PHOENIX_DRIVER_NOT_INSTALLED_ERROR, PHOENIX_JDBC_PLUGIN_NOT_INSTALLED_ERROR } from "@/lib/database/phoenixConnection"; import { PHOENIX_DRIVER_NOT_INSTALLED_ERROR, PHOENIX_JDBC_PLUGIN_NOT_INSTALLED_ERROR } from "@/lib/database/phoenixConnection";
const LOCALES = { const LOCALES = {
az,
en, en,
es, es,
it, it,
@@ -1,5 +1,6 @@
import { readFileSync } from "node:fs"; import { readFileSync } from "node:fs";
import { describe, expect, it as test } from "vitest"; import { describe, expect, it as test } from "vitest";
import az from "@/i18n/locales/az";
import en from "@/i18n/locales/en"; import en from "@/i18n/locales/en";
import es from "@/i18n/locales/es"; import es from "@/i18n/locales/es";
import it from "@/i18n/locales/it"; import it from "@/i18n/locales/it";
@@ -18,6 +19,7 @@ function cachedResultMessages(messages: Record<string, unknown>): Record<string,
describe("cached result messages", () => { describe("cached result messages", () => {
test.each([ test.each([
["Azerbaijani", az],
["English", en], ["English", en],
["Spanish", es], ["Spanish", es],
["Italian", it], ["Italian", it],
@@ -1,5 +1,6 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { readFileSync } from "node:fs"; import { readFileSync } from "node:fs";
import az from "../locales/az";
import en from "../locales/en"; import en from "../locales/en";
import es from "../locales/es"; import es from "../locales/es";
import it_ from "../locales/it"; import it_ from "../locales/it";
@@ -11,6 +12,7 @@ import zhCN from "../locales/zh-CN";
import zhTW from "../locales/zh-TW"; import zhTW from "../locales/zh-TW";
const locales: Array<[string, Record<string, unknown>]> = [ const locales: Array<[string, Record<string, unknown>]> = [
["az", az],
["en", en], ["en", en],
["es", es], ["es", es],
["it", it_], ["it", it_],
+2 -1
View File
@@ -1,4 +1,5 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import az from "@/i18n/locales/az";
import en from "@/i18n/locales/en"; import en from "@/i18n/locales/en";
import es from "@/i18n/locales/es"; import es from "@/i18n/locales/es";
import itLocale from "@/i18n/locales/it"; import itLocale from "@/i18n/locales/it";
@@ -14,7 +15,7 @@ type Messages = {
contextMenu: typeof en.contextMenu; contextMenu: typeof en.contextMenu;
}; };
const locales = { es, it: itLocale, ja, ko, "pt-BR": ptBR, tr, "zh-CN": zhCN, "zh-TW": zhTW } as unknown as Record<string, Messages>; const locales = { az, es, it: itLocale, ja, ko, "pt-BR": ptBR, tr, "zh-CN": zhCN, "zh-TW": zhTW } as unknown as Record<string, Messages>;
describe("custom type translations", () => { describe("custom type translations", () => {
it("provides localized labels in every supported non-English locale", () => { it("provides localized labels in every supported non-English locale", () => {
@@ -1,4 +1,5 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import az from "../locales/docs/az";
import en from "../locales/docs/en"; import en from "../locales/docs/en";
import es from "../locales/docs/es"; import es from "../locales/docs/es";
import it_ from "../locales/docs/it"; import it_ from "../locales/docs/it";
@@ -17,6 +18,7 @@ import zhTW from "../locales/docs/zh-TW";
// have every key and this test would pass while translations were missing — // have every key and this test would pass while translations were missing —
// the fallback would silently defeat the test written to catch it. // the fallback would silently defeat the test written to catch it.
const locales: Array<[string, Record<string, unknown>]> = [ const locales: Array<[string, Record<string, unknown>]> = [
["az", az],
["es", es], ["es", es],
["it", it_], ["it", it_],
["ja", ja], ["ja", ja],
@@ -1,4 +1,5 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import az from "../locales/az";
import en from "../locales/en"; import en from "../locales/en";
import es from "../locales/es"; import es from "../locales/es";
import it_ from "../locales/it"; import it_ from "../locales/it";
@@ -12,6 +13,7 @@ import zhTW from "../locales/zh-TW";
type Messages = Record<string, unknown>; type Messages = Record<string, unknown>;
const locales: Array<[string, Messages]> = [ const locales: Array<[string, Messages]> = [
["az", az],
["es", es], ["es", es],
["it", it_], ["it", it_],
["ja", ja], ["ja", ja],
@@ -1,4 +1,5 @@
import { describe, expect, it as test } from "vitest"; import { describe, expect, it as test } from "vitest";
import az from "@/i18n/locales/az";
import en from "@/i18n/locales/en"; import en from "@/i18n/locales/en";
import es from "@/i18n/locales/es"; import es from "@/i18n/locales/es";
import it from "@/i18n/locales/it"; import it from "@/i18n/locales/it";
@@ -16,6 +17,7 @@ function sqliteRebuildNotice(messages: Record<string, unknown>): string {
describe("SQLite rebuild notice", () => { describe("SQLite rebuild notice", () => {
test.each([ test.each([
["Azerbaijani", az],
["English", en], ["English", en],
["Spanish", es], ["Spanish", es],
["Italian", it], ["Italian", it],
@@ -1,4 +1,5 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import az from "../locales/az";
import en from "../locales/en"; import en from "../locales/en";
import es from "../locales/es"; import es from "../locales/es";
import it_ from "../locales/it"; import it_ from "../locales/it";
@@ -23,6 +24,7 @@ const tabMenuKeys = ["changeOrientation", "closeAllTabs", "closeLeftTabs", "clos
// real text for every UI language, while the en test above is the one that // real text for every UI language, while the en test above is the one that
// actually catches a missing-from-everywhere key. // actually catches a missing-from-everywhere key.
const locales: Array<[string, Record<string, unknown>]> = [ const locales: Array<[string, Record<string, unknown>]> = [
["az", az as Record<string, unknown>],
["en", en as Record<string, unknown>], ["en", en as Record<string, unknown>],
["es", es], ["es", es],
["it", it_], ["it", it_],
@@ -1,4 +1,5 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import az from "../locales/az";
import en from "../locales/en"; import en from "../locales/en";
import es from "../locales/es"; import es from "../locales/es";
import it_ from "../locales/it"; import it_ from "../locales/it";
@@ -11,6 +12,7 @@ import zhTW from "../locales/zh-TW";
const locales: Array<[string, Record<string, unknown>]> = [ const locales: Array<[string, Record<string, unknown>]> = [
["en", en as Record<string, unknown>], ["en", en as Record<string, unknown>],
["az", az as Record<string, unknown>],
["es", es], ["es", es],
["it", it_], ["it", it_],
["ja", ja], ["ja", ja],
@@ -1,4 +1,5 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import az from "@/i18n/locales/az";
import en from "@/i18n/locales/en"; import en from "@/i18n/locales/en";
import es from "@/i18n/locales/es"; import es from "@/i18n/locales/es";
import itLocale from "@/i18n/locales/it"; import itLocale from "@/i18n/locales/it";
@@ -16,7 +17,7 @@ describe("user administration Host translations", () => {
}); });
it("provides localized Host-change labels in every non-English locale", () => { it("provides localized Host-change labels in every non-English locale", () => {
const locales = { es, it: itLocale, ja, ko, "pt-BR": ptBR, tr, "zh-CN": zhCN, "zh-TW": zhTW }; const locales = { az, es, it: itLocale, ja, ko, "pt-BR": ptBR, tr, "zh-CN": zhCN, "zh-TW": zhTW };
for (const [locale, messages] of Object.entries(locales)) { for (const [locale, messages] of Object.entries(locales)) {
expect(messages.userAdmin.changeHost, locale).not.toBe(en.userAdmin.changeHost); expect(messages.userAdmin.changeHost, locale).not.toBe(en.userAdmin.changeHost);
expect(messages.userAdmin.newHost, locale).not.toBe(en.userAdmin.newHost); expect(messages.userAdmin.newHost, locale).not.toBe(en.userAdmin.newHost);
+4 -2
View File
@@ -3,17 +3,18 @@ import en from "./locales/en";
import { safeLocalStorageGet, safeLocalStorageSet } from "@/lib/backend/safeStorage"; import { safeLocalStorageGet, safeLocalStorageSet } from "@/lib/backend/safeStorage";
import { isTauriRuntime } from "@/lib/backend/tauriRuntime"; import { isTauriRuntime } from "@/lib/backend/tauriRuntime";
export type Locale = "en" | "es" | "it" | "ja" | "ko" | "pt-BR" | "tr" | "zh-CN" | "zh-TW"; export type Locale = "az" | "en" | "es" | "it" | "ja" | "ko" | "pt-BR" | "tr" | "zh-CN" | "zh-TW";
type LocaleMessages = Record<string, unknown>; type LocaleMessages = Record<string, unknown>;
type I18nGlobal = { type I18nGlobal = {
locale: { value: Locale }; locale: { value: Locale };
setLocaleMessage: (locale: Locale, messages: LocaleMessages) => void; setLocaleMessage: (locale: Locale, messages: LocaleMessages) => void;
}; };
const supportedLocales: Locale[] = ["en", "es", "it", "ja", "ko", "pt-BR", "tr", "zh-CN", "zh-TW"]; const supportedLocales: Locale[] = ["az", "en", "es", "it", "ja", "ko", "pt-BR", "tr", "zh-CN", "zh-TW"];
const defaultLocale: Locale = "en"; const defaultLocale: Locale = "en";
const loadedLocales = new Set<Locale>([defaultLocale]); const loadedLocales = new Set<Locale>([defaultLocale]);
const localeLoaders: Record<Exclude<Locale, "en">, () => Promise<{ default: LocaleMessages }>> = { const localeLoaders: Record<Exclude<Locale, "en">, () => Promise<{ default: LocaleMessages }>> = {
az: () => import("./locales/az"),
es: () => import("./locales/es"), es: () => import("./locales/es"),
it: () => import("./locales/it"), it: () => import("./locales/it"),
ja: () => import("./locales/ja"), ja: () => import("./locales/ja"),
@@ -40,6 +41,7 @@ export function localeFromLanguageTag(value: string | null | undefined): Locale
} }
return "zh-CN"; return "zh-CN";
} }
if (normalized === "az" || normalized.startsWith("az-")) return "az";
if (normalized === "en" || normalized.startsWith("en-")) return "en"; if (normalized === "en" || normalized.startsWith("en-")) return "en";
if (normalized === "es" || normalized.startsWith("es-")) return "es"; if (normalized === "es" || normalized.startsWith("es-")) return "es";
if (normalized === "it" || normalized.startsWith("it-")) return "it"; if (normalized === "it" || normalized.startsWith("it-")) return "it";
File diff suppressed because it is too large. Load diff
+69
View File
@@ -0,0 +1,69 @@
export default {
title: "Sənədləşdirmə",
groupBySchema: "Sxemlər",
groupByTableGroup: "Cədvəl qrupları",
noGroup: "(qrup yoxdur)",
noSchema: "(sxem yoxdur)",
search: "Cədvəlləri, sütunları, qrupları axtar…",
columns: "Sütunlar",
indexes: "İndekslər",
references: "İstinadlar",
referencedBy: "İstinad edənlər",
localNote: "Yerli",
shadowedComment: "Verilənlər bazasındakı şərh: {comment}",
addNote: "Qeyd əlavə et",
editNote: "Qeydi redaktə et",
newGroup: "Yeni qrup…",
groupName: "Qrupun adı",
groupColour: "Rəng",
deleteGroup: "Qrupu sil",
enumValues: "Dəyərlər",
usedBy: "İstifadə edənlər",
openDiagram: "Sxem diaqramını aç",
saving: "Yadda saxlanılır…",
saved: "Yadda saxlanıldı",
saveFailed: "Qeydləri yadda saxlamaq mümkün olmadı: {error}",
overview: "Ümumi baxış",
groupBy: "Qruplaşdırma meyarı",
searchLabel: "Axtarış",
groups: "Qruplar",
relationships: "Əlaqələr",
columnHeader: "Sütun",
typeHeader: "Növ",
settingsHeader: "Parametrlər",
noteHeader: "Qeyd",
nameHeader: "Ad",
definitionHeader: "Tərif",
noOutgoingRelationships: "Bu cədvəl başqa heç bir cədvələ istinad etmir.",
noIncomingRelationships: "Heç bir cədvəl bu cədvələ istinad etmir.",
diagram: "Diaqram",
language: "Dil",
theme: "Tema",
themeLight: "Açıq",
themeDark: "Tünd",
exportHtml: "HTML-ə ixrac et…",
exporting: "İxrac edilir…",
exportFailed: "İxrac etmək mümkün olmadı: {error}",
warnings: {
tableSkipped: {
title: "Bir cədvəli sənədləşdirmək mümkün olmadı",
detail: "{table} ötürüldü: {reason}. Bu sənədləşdirmədə yer almır.",
},
noForeignKeyMetadata: {
title: "Əlaqələr mövcud deyil",
detail: "{engine} xarici açar metaverilənlərini təqdim etmir, buna görə əlaqə xətlərini müəyyən etmək mümkün olmadı. Bu mühərrik üçün diaqram tamdır.",
},
commentsUnsupported: {
title: "Verilənlər bazasının şərhləri əlçatan deyil",
detail: "{engine} cədvəl və ya sütun şərhlərini dəstəkləmir, buna görə buradakı bütün təsvirlər bu layihənin öz qeydlərindən götürülüb.",
},
orphanedNotes: {
title: "Bəzi qeydlər artıq heç nəyə uyğun gəlmir",
detail: "{count} qeyd artıq mövcud olmayan cədvələ və ya sütuna istinad edir. Heç nə silinməyib — qeydlər faylında onları yenidən uyğunlaşdırın və ya çıxarın.",
},
dbmlOmitted: {
title: "DBML-də ifadə etmək mümkün deyil",
detail: "{table} cədvəlindəki {item} burada sənədləşdirilib, lakin ixrac edilmiş DBML-ə daxil edilməyib: {reason}.",
},
},
};
@@ -220,6 +220,34 @@ const zhCN = {
}; };
export const meilisearchManagementMessages = { export const meilisearchManagementMessages = {
az: {
...en,
systemManagement: "Sistemin idarə edilməsi",
overview: "Ümumi baxış",
apiKeys: "API açarları",
tasks: "Tapşırıqlar",
health: "İşlək vəziyyət",
version: "Versiya",
indexCount: "İndekslər",
totalDocuments: "Sənədlərin ümumi sayı",
keyCount: "Açarlar",
refresh: "Yenilə",
rowActions: "Əməliyyatlar",
previous: "Əvvəlki",
next: "Növbəti",
createKey: "Açar yarat",
editKey: "Açarı redaktə et",
deleteKey: "Açarı sil",
noKeys: "API açarları tapılmadı",
filters: "Süzgəclər",
applyFilters: "Süzgəcləri tətbiq et",
receivedDocuments: "Qəbul edilmiş sənədlər",
indexedDocuments: "İndekslənmiş sənədlər",
noTasks: "Tapşırıqlar tapılmadı",
cancelTask: "Tapşırığı ləğv et",
deleteTaskHistory: "Tapşırıq tarixçəsini sil",
readOnlyDisabled: "Bu əlaqə yalnız oxumaq üçündür; idarəetmə əməliyyatları deaktivdir.",
},
en, en,
"zh-CN": zhCN, "zh-CN": zhCN,
"zh-TW": { "zh-TW": {
@@ -415,6 +443,7 @@ export const meilisearchManagementMessages = {
}, },
} as const; } as const;
export const meilisearchManagementAz = meilisearchManagementMessages.az;
export const meilisearchManagementEn = meilisearchManagementMessages.en; export const meilisearchManagementEn = meilisearchManagementMessages.en;
export const meilisearchManagementZhCN = meilisearchManagementMessages["zh-CN"]; export const meilisearchManagementZhCN = meilisearchManagementMessages["zh-CN"];
export const meilisearchManagementZhTW = meilisearchManagementMessages["zh-TW"]; export const meilisearchManagementZhTW = meilisearchManagementMessages["zh-TW"];
@@ -4,7 +4,7 @@ import { describe, expect, it } from "vitest";
const dialogSource = readFileSync(new URL("../../../components/connection/ConnectionDialog.vue", import.meta.url), "utf8"); const dialogSource = readFileSync(new URL("../../../components/connection/ConnectionDialog.vue", import.meta.url), "utf8");
const enSource = readFileSync(new URL("../../../i18n/locales/en.ts", import.meta.url), "utf8"); const enSource = readFileSync(new URL("../../../i18n/locales/en.ts", import.meta.url), "utf8");
const zhCnSource = readFileSync(new URL("../../../i18n/locales/zh-CN.ts", import.meta.url), "utf8"); const zhCnSource = readFileSync(new URL("../../../i18n/locales/zh-CN.ts", import.meta.url), "utf8");
const fallbackLocaleSources = ["es", "it", "ja", "ko", "pt-BR", "tr", "zh-TW"].map((locale) => readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8")); const fallbackLocaleSources = ["az", "es", "it", "ja", "ko", "pt-BR", "tr", "zh-TW"].map((locale) => readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8"));
describe("ZooKeeper connection dialog", () => { describe("ZooKeeper connection dialog", () => {
it("binds the existing Select component to the ZooKeeper auth_scheme helper", () => { it("binds the existing Select component to the ZooKeeper auth_scheme helper", () => {
@@ -2,6 +2,7 @@ import type { Locale } from "@/i18n";
export const LOCALE_OPTIONS: { value: Locale; flag: string; label: string }[] = [ export const LOCALE_OPTIONS: { value: Locale; flag: string; label: string }[] = [
{ value: "en", flag: "🇺🇸", label: "English" }, { value: "en", flag: "🇺🇸", label: "English" },
{ value: "az", flag: "🇦🇿", label: "Azərbaycan" },
{ value: "es", flag: "🇪🇸", label: "Español" }, { value: "es", flag: "🇪🇸", label: "Español" },
{ value: "it", flag: "🇮🇹", label: "Italiano" }, { value: "it", flag: "🇮🇹", label: "Italiano" },
{ value: "ja", flag: "🇯🇵", label: "日本語" }, { value: "ja", flag: "🇯🇵", label: "日本語" },
@@ -146,7 +146,7 @@ describe("settings search", () => {
}); });
it("defines the WebDAV Web-runtime notice in every supported locale", () => { it("defines the WebDAV Web-runtime notice in every supported locale", () => {
for (const locale of ["zh-CN", "zh-TW", "en", "es", "it", "ja", "ko", "pt-BR", "tr"]) { for (const locale of ["zh-CN", "zh-TW", "en", "es", "it", "ja", "ko", "pt-BR", "tr", "az"]) {
const source = readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8"); const source = readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8");
expect(source, locale).toContain("syncWebDavWebDescription:"); expect(source, locale).toContain("syncWebDavWebDescription:");
} }
@@ -257,7 +257,7 @@ describe("settings search", () => {
}); });
it("defines the performance section title in every supported locale", () => { it("defines the performance section title in every supported locale", () => {
for (const locale of ["zh-CN", "zh-TW", "en", "es", "it", "ja", "ko", "pt-BR", "tr"]) { for (const locale of ["zh-CN", "zh-TW", "en", "es", "it", "ja", "ko", "pt-BR", "tr", "az"]) {
const source = readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8"); const source = readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8");
expect(source, locale).toContain("performanceSection:"); expect(source, locale).toContain("performanceSection:");
} }
+1 -1
View File
@@ -61,4 +61,4 @@ ${this.parser.parse(e)}</blockquote>
${e}</tr> ${e}</tr>
`}tablecell(e){let t=this.parser.parseInline(e.tokens),n=e.header?`th`:`td`;return(e.align?`<${n} align="${e.align}">`:`<${n}>`)+t+`</${n}> `}tablecell(e){let t=this.parser.parseInline(e.tokens),n=e.header?`th`:`td`;return(e.align?`<${n} align="${e.align}">`:`<${n}>`)+t+`</${n}>
`}strong({tokens:e}){return`<strong>${this.parser.parseInline(e)}</strong>`}em({tokens:e}){return`<em>${this.parser.parseInline(e)}</em>`}codespan({text:e}){return`<code>${ec(e,!0)}</code>`}br(e){return`<br>`}del({tokens:e}){return`<del>${this.parser.parseInline(e)}</del>`}link({href:e,title:t,tokens:n}){let r=this.parser.parseInline(n),i=tc(e);if(i===null)return r;e=i;let a=`<a href="`+e+`"`;return t&&(a+=` title="`+ec(t)+`"`),a+=`>`+r+`</a>`,a}image({href:e,title:t,text:n,tokens:r}){r&&(n=this.parser.parseInline(r,this.parser.textRenderer));let i=tc(e);if(i===null)return ec(n);e=i;let a=`<img src="${e}" alt="${ec(n)}"`;return t&&(a+=` title="${ec(t)}"`),a+=`>`,a}text(e){return`tokens`in e&&e.tokens?this.parser.parseInline(e.tokens):`escaped`in e&&e.escaped?e.text:ec(e.text)}},fc=class{strong({text:e}){return e}em({text:e}){return e}codespan({text:e}){return e}del({text:e}){return e}html({text:e}){return e}text({text:e}){return e}link({text:e}){return``+e}image({text:e}){return``+e}br(){return``}checkbox({raw:e}){return e}},pc=class e{options;renderer;textRenderer;constructor(e){this.options=e||Ho,this.options.renderer=this.options.renderer||new dc,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new fc}static parse(t,n){return new e(n).parse(t)}static parseInline(t,n){return new e(n).parseInline(t)}parse(e){this.renderer.parser=this;let t=``;for(let n=0;n<e.length;n++){let r=e[n];if(this.options.extensions?.renderers?.[r.type]){let e=r,n=this.options.extensions.renderers[e.type].call({parser:this},e);if(n!==!1||![`space`,`hr`,`heading`,`code`,`table`,`blockquote`,`list`,`html`,`def`,`paragraph`,`text`].includes(e.type)){t+=n||``;continue}}let i=r;switch(i.type){case`space`:t+=this.renderer.space(i);break;case`hr`:t+=this.renderer.hr(i);break;case`heading`:t+=this.renderer.heading(i);break;case`code`:t+=this.renderer.code(i);break;case`table`:t+=this.renderer.table(i);break;case`blockquote`:t+=this.renderer.blockquote(i);break;case`list`:t+=this.renderer.list(i);break;case`checkbox`:t+=this.renderer.checkbox(i);break;case`html`:t+=this.renderer.html(i);break;case`def`:t+=this.renderer.def(i);break;case`paragraph`:t+=this.renderer.paragraph(i);break;case`text`:t+=this.renderer.text(i);break;default:{let e=`Token with "`+i.type+`" type was not found.`;if(this.options.silent)return console.error(e),``;throw Error(e)}}}return t}parseInline(e,t=this.renderer){this.renderer.parser=this;let n=``;for(let r=0;r<e.length;r++){let i=e[r];if(this.options.extensions?.renderers?.[i.type]){let e=this.options.extensions.renderers[i.type].call({parser:this},i);if(e!==!1||![`escape`,`html`,`link`,`image`,`strong`,`em`,`codespan`,`br`,`del`,`text`].includes(i.type)){n+=e||``;continue}}let a=i;switch(a.type){case`escape`:n+=t.text(a);break;case`html`:n+=t.html(a);break;case`link`:n+=t.link(a);break;case`image`:n+=t.image(a);break;case`checkbox`:n+=t.checkbox(a);break;case`strong`:n+=t.strong(a);break;case`em`:n+=t.em(a);break;case`codespan`:n+=t.codespan(a);break;case`br`:n+=t.br(a);break;case`del`:n+=t.del(a);break;case`text`:n+=t.text(a);break;default:{let e=`Token with "`+a.type+`" type was not found.`;if(this.options.silent)return console.error(e),``;throw Error(e)}}}return n}},mc=class{options;block;constructor(e){this.options=e||Ho}static passThroughHooks=new Set([`preprocess`,`postprocess`,`processAllTokens`,`emStrongMask`]);static passThroughHooksRespectAsync=new Set([`preprocess`,`postprocess`,`processAllTokens`]);preprocess(e){return e}postprocess(e){return e}processAllTokens(e){return e}emStrongMask(e){return e}provideLexer(e=this.block){return e?uc.lex:uc.lexInline}provideParser(e=this.block){return e?pc.parse:pc.parseInline}},hc=class{defaults=Vo();options=this.setOptions;parse=this.parseMarkdown(!0);parseInline=this.parseMarkdown(!1);Parser=pc;Renderer=dc;TextRenderer=fc;Lexer=uc;Tokenizer=lc;Hooks=mc;constructor(...e){this.use(...e)}walkTokens(e,t){let n=[];for(let r of e)switch(n=n.concat(t.call(this,r)),r.type){case`table`:{let e=r;for(let r of e.header)n=n.concat(this.walkTokens(r.tokens,t));for(let r of e.rows)for(let e of r)n=n.concat(this.walkTokens(e.tokens,t));break}case`list`:{let e=r;n=n.concat(this.walkTokens(e.items,t));break}default:{let e=r;this.defaults.extensions?.childTokens?.[e.type]?this.defaults.extensions.childTokens[e.type].forEach(r=>{let i=e[r].flat(1/0);n=n.concat(this.walkTokens(i,t))}):e.tokens&&(n=n.concat(this.walkTokens(e.tokens,t)))}}return n}use(...e){let t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(e=>{let n={...e};if(n.async=this.defaults.async||n.async||!1,e.extensions&&(e.extensions.forEach(e=>{if(!e.name)throw Error(`extension name required`);if(`renderer`in e){let n=t.renderers[e.name];n?t.renderers[e.name]=function(...t){let r=e.renderer.apply(this,t);return r===!1&&(r=n.apply(this,t)),r}:t.renderers[e.name]=e.renderer}if(`tokenizer`in e){if(!e.level||e.level!==`block`&&e.levelLine truncated `}strong({tokens:e}){return`<strong>${this.parser.parseInline(e)}</strong>`}em({tokens:e}){return`<em>${this.parser.parseInline(e)}</em>`}codespan({text:e}){return`<code>${ec(e,!0)}</code>`}br(e){return`<br>`}del({tokens:e}){return`<del>${this.parser.parseInline(e)}</del>`}link({href:e,title:t,tokens:n}){let r=this.parser.parseInline(n),i=tc(e);if(i===null)return r;e=i;let a=`<a href="`+e+`"`;return t&&(a+=` title="`+ec(t)+`"`),a+=`>`+r+`</a>`,a}image({href:e,title:t,text:n,tokens:r}){r&&(n=this.parser.parseInline(r,this.parser.textRenderer));let i=tc(e);if(i===null)return ec(n);e=i;let a=`<img src="${e}" alt="${ec(n)}"`;return t&&(a+=` title="${ec(t)}"`),a+=`>`,a}text(e){return`tokens`in e&&e.tokens?this.parser.parseInline(e.tokens):`escaped`in e&&e.escaped?e.text:ec(e.text)}},fc=class{strong({text:e}){return e}em({text:e}){return e}codespan({text:e}){return e}del({text:e}){return e}html({text:e}){return e}text({text:e}){return e}link({text:e}){return``+e}image({text:e}){return``+e}br(){return``}checkbox({raw:e}){return e}},pc=class e{options;renderer;textRenderer;constructor(e){this.options=e||Ho,this.options.renderer=this.options.renderer||new dc,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new fc}static parse(t,n){return new e(n).parse(t)}static parseInline(t,n){return new e(n).parseInline(t)}parse(e){this.renderer.parser=this;let t=``;for(let n=0;n<e.length;n++){let r=e[n];if(this.options.extensions?.renderers?.[r.type]){let e=r,n=this.options.extensions.renderers[e.type].call({parser:this},e);if(n!==!1||![`space`,`hr`,`heading`,`code`,`table`,`blockquote`,`list`,`html`,`def`,`paragraph`,`text`].includes(e.type)){t+=n||``;continue}}let i=r;switch(i.type){case`space`:t+=this.renderer.space(i);break;case`hr`:t+=this.renderer.hr(i);break;case`heading`:t+=this.renderer.heading(i);break;case`code`:t+=this.renderer.code(i);break;case`table`:t+=this.renderer.table(i);break;case`blockquote`:t+=this.renderer.blockquote(i);break;case`list`:t+=this.renderer.list(i);break;case`checkbox`:t+=this.renderer.checkbox(i);break;case`html`:t+=this.renderer.html(i);break;case`def`:t+=this.renderer.def(i);break;case`paragraph`:t+=this.renderer.paragraph(i);break;case`text`:t+=this.renderer.text(i);break;default:{let e=`Token with "`+i.type+`" type was not found.`;if(this.options.silent)return console.error(e),``;throw Error(e)}}}return t}parseInline(e,t=this.renderer){this.renderer.parser=this;let n=``;for(let r=0;r<e.length;r++){let i=e[r];if(this.options.extensions?.renderers?.[i.type]){let e=this.options.extensions.renderers[i.type].call({parser:this},i);if(e!==!1||![`escape`,`html`,`link`,`image`,`strong`,`em`,`codespan`,`br`,`del`,`text`].includes(i.type)){n+=e||``;continue}}let a=i;switch(a.type){case`escape`:n+=t.text(a);break;case`html`:n+=t.html(a);break;case`link`:n+=t.link(a);break;case`image`:n+=t.image(a);break;case`checkbox`:n+=t.checkbox(a);break;case`strong`:n+=t.strong(a);break;case`em`:n+=t.em(a);break;case`codespan`:n+=t.codespan(a);break;case`br`:n+=t.br(a);break;case`del`:n+=t.del(a);break;case`text`:n+=t.text(a);break;default:{let e=`Token with "`+a.type+`" type was not found.`;if(this.options.silent)return console.error(e),``;throw Error(e)}}}return n}},mc=class{options;block;constructor(e){this.options=e||Ho}static passThroughHooks=new Set([`preprocess`,`postprocess`,`processAllTokens`,`emStrongMask`]);static passThroughHooksRespectAsync=new Set([`preprocess`,`postprocess`,`processAllTokens`]);preprocess(e){return e}postprocess(e){return e}processAllTokens(e){return e}emStrongMask(e){return e}provideLexer(e=this.block){return e?uc.lex:uc.lexInline}provideParser(e=this.block){return e?pc.parse:pc.parseInline}},hc=class{defaults=Vo();options=this.setOptions;parse=this.parseMarkdown(!0);parseInline=this.parseMarkdown(!1);Parser=pc;Renderer=dc;TextRenderer=fc;Lexer=uc;Tokenizer=lc;Hooks=mc;constructor(...e){this.use(...e)}walkTokens(e,t){let n=[];for(let r of e)switch(n=n.concat(t.call(this,r)),r.type){case`table`:{let e=r;for(let r of e.header)n=n.concat(this.walkTokens(r.tokens,t));for(let r of e.rows)for(let e of r)n=n.concat(this.walkTokens(e.tokens,t));break}case`list`:{let e=r;n=n.concat(this.walkTokens(e.items,t));break}default:{let e=r;this.defaults.extensions?.childTokens?.[e.type]?this.defaults.extensions.childTokens[e.type].forEach(r=>{let i=e[r].flat(1/0);n=n.concat(this.walkTokens(i,t))}):e.tokens&&(n=n.concat(this.walkTokens(e.tokens,t)))}}return n}use(...e){let t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(e=>{let n={...e};if(n.async=this.defaults.async||n.async||!1,e.extensions&&(e.extensions.forEach(e=>{if(!e.name)throw Error(`extension name required`);if(`renderer`in e){let n=t.renderers[e.name];n?t.renderers[e.name]=function(...t){let r=e.renderer.apply(this,t);return r===!1&&(r=n.apply(this,t)),r}:t.renderers[e.name]=e.renderer}if(`tokenizer`in e){if(!e.level||e.level!==`block`&&e.levelLine truncated
Please report this to https://github.com/markedjs/marked.`,e){let e=`<p>An error occurred:</p><pre>`+ec(n.message+``,!0)+`</pre>`;return t?Promise.resolve(e):e}if(t)return Promise.reject(n);throw n}}},gc=new hc;function $(e,t){return gc.parse(e,t)}$.options=$.setOptions=function(e){return gc.setOptions(e),$.defaults=gc.defaults,Uo($.defaults),$},$.getDefaults=Vo,$.defaults=Ho,$.use=function(...e){return gc.use(...e),$.defaults=gc.defaults,Uo($.defaults),$},$.walkTokens=function(e,t){return gc.walkTokens(e,t)},$.parseInline=gc.parseInline,$.Parser=pc,$.parser=pc.parse,$.Renderer=dc,$.TextRenderer=fc,$.Lexer=uc,$.lexer=uc.lex,$.Tokenizer=lc,$.Hooks=mc,$.parse=$,$.options,$.setOptions,$.use,$.walkTokens,$.parseInline,pc.parse,uc.lex;function _c(e){return String(e??``).replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&#39;`)}var vc=/^(https?:|mailto:)/i;function yc(e){let t=String(e??``).trim();return t===``||/^[/\\]{2}/.test(t)?null:t.startsWith(`#`)||t.startsWith(`/`)||t.startsWith(`./`)||t.startsWith(`../`)||vc.test(t)?t:null}var bc=new hc({renderer:{html({text:e}){return _c(e)},link({href:e,title:t,tokens:n}){let r=this.parser.parseInline(n),i=yc(e);if(i===null)return r;let a=t?` title="${_c(t)}"`:``;return`<a href="${_c(i)}"${a}>${r}</a>`},image({href:e,title:t,text:n}){let r=yc(e);if(r===null)return _c(n);let i=t?` title="${_c(t)}"`:``;return`<img src="${_c(r)}" alt="${_c(n)}"${i}>`}}});function xc(e){return e===null||e.trim()===``?``:bc.parse(e)}var Sc={class:`text-sm text-muted-foreground`},Cc=[`title`,`innerHTML`],wc=L({__name:`NoteEditor`,props:{modelValue:{},readonly:{type:Boolean},translate:{type:Function}},emits:[`update:modelValue`],setup(e,{emit:t}){let n=e,r=t,i=P(!1),a=P(``),o=P(null);async function s(){n.readonly||(a.value=n.modelValue,i.value=!0,await hn(),o.value?.focus())}function c(){i.value=!1,a.value!==n.modelValue&&r(`update:modelValue`,a.value)}function l(){a.value=n.modelValue,i.value=!1}return(t,n)=>(U(),W(`div`,Sc,[i.value?On((U(),W(`textarea`,{key:0,ref_key:`input`,ref:o,"onUpdate:modelValue":n[0]||=e=>a.value=e,rows:`4`,class:`w-full resize-y rounded border border-border bg-background p-2 font-mono text-xs text-foreground outline-none focus:border-ring`,onBlur:n[1]||=e=>c(),onKeydown:n[2]||=lo(e=>l(),[`escape`])},null,544)),[[to,a.value]]):e.modelValue.trim()===``?e.readonly?q(``,!0):(U(),W(`button`,{key:2,type:`button`,class:`rounded border border-dashed border-border px-2 py-1 text-xs text-muted-foreground transition-colors hover:bg-muted/40`,onClick:n[4]||=e=>s()},O(e.translate(`docs.addNote`)),1)):(U(),W(`div`,{key:1,class:D([`leading-relaxed`,e.readonly?``:`cursor-text rounded transition-colors hover:bg-muted/30`]),title:e.readonly?void 0:e.translate(`docs.editNote`),onClick:n[3]||=e=>s(),innerHTML:F(xc)(e.modelValue)},null,10,Cc))]))}}),Tc={class:`flex flex-col gap-5`},Ec={class:`flex flex-col gap-2`},Dc={class:`flex flex-wrap items-center gap-2`},Oc={class:`font-mono text-lg font-semibold text-foreground`},kc={key:0,class:`rounded bg-muted/50 px-1.5 py-0.5 text-[10px] uppercase text-muted-foreground`},Ac={class:`mb-1.5 text-xs font-semibold uppercase tracking-wide text-muted-foreground`},jc={class:`flex flex-wrap gap-1`},Mc={class:`mb-1.5 text-xs font-semibold uppercase tracking-wide text-muted-foreground`},Nc={key:0,class:`text-xs text-muted-foreground`},Pc={key:1,class:`flex flex-col gap-1`},Fc=[`onClick`],Ic=L({__name:`EnumPage`,props:{enumType:{},snapshot:{},translate:{type:Function}},emits:[`select`],setup(e,{emit:t}){let n=e,r=t,i=Y(()=>n.enumType.schema?`${n.enumType.schema}.${n.enumType.name}`:n.enumType.name),a=Y(()=>Bo(n.snapshot,n.enumType.name));return(t,n)=>(U(),W(`article`,Tc,[G(`header`,Ec,[G(`div`,Dc,[G(`h2`,Oc,O(i.value),1),e.enumType.synthesized?(U(),W(`span`,kc,`synthesized`)):q(``,!0)]),K(wc,{"model-value":e.enumType.note??``,readonly:``,translate:e.translate},null,8,[`model-value`,`translate`])]),G(`section`,null,[G(`h3`,Ac,O(e.translate(`docs.enumValues`)),1),G(`ul`,jc,[(U(!0),W(V,null,R(e.enumType.values,e=>(U(),W(`li`,{key:e,class:`rounded bg-muted/50 px-1.5 py-0.5 font-mono text-[11px] text-foreground`},O(e),1))),128))])]),G(`section`,null,[G(`h3`,Mc,O(e.translate(`docs.usedBy`)),1),a.value.length===0?(U(),W(`p`,Nc,`No column uses this enum.`)):(U(),W(`ul`,Pc,[(U(!0),W(V,null,R(a.value,e=>(U(),W(`li`,{key:`${e.tableKey}.${e.column}`,class:`text-xs`},[G(`button`,{type:`button`,class:`w-full rounded border border-border bg-background px-2 py-1.5 text-left font-mono transition-colors hover:bg-muted/40`,onClick:t=>r(`select`,e.tableKey)},O(e.tableKey)+`.`+O(e.column),9,Fc)]))),128))]))])]))}}),Lc={class:`flex flex-col gap-3`},Rc={class:`flex flex-col gap-1`},zc={class:`text-[10px] uppercase tracking-wide text-muted-foreground`},Bc=[`value`,`placeholder`],Vc={class:`flex flex-col gap-2`},Hc={class:`text-[10px] uppercase tracking-wide text-muted-foreground`},Uc={class:`flex items-center gap-1.5`},Wc=[`t Line truncated Please report this to https://github.com/markedjs/marked.`,e){let e=`<p>An error occurred:</p><pre>`+ec(n.message+``,!0)+`</pre>`;return t?Promise.resolve(e):e}if(t)return Promise.reject(n);throw n}}},gc=new hc;function $(e,t){return gc.parse(e,t)}$.options=$.setOptions=function(e){return gc.setOptions(e),$.defaults=gc.defaults,Uo($.defaults),$},$.getDefaults=Vo,$.defaults=Ho,$.use=function(...e){return gc.use(...e),$.defaults=gc.defaults,Uo($.defaults),$},$.walkTokens=function(e,t){return gc.walkTokens(e,t)},$.parseInline=gc.parseInline,$.Parser=pc,$.parser=pc.parse,$.Renderer=dc,$.TextRenderer=fc,$.Lexer=uc,$.lexer=uc.lex,$.Tokenizer=lc,$.Hooks=mc,$.parse=$,$.options,$.setOptions,$.use,$.walkTokens,$.parseInline,pc.parse,uc.lex;function _c(e){return String(e??``).replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&#39;`)}var vc=/^(https?:|mailto:)/i;function yc(e){let t=String(e??``).trim();return t===``||/^[/\\]{2}/.test(t)?null:t.startsWith(`#`)||t.startsWith(`/`)||t.startsWith(`./`)||t.startsWith(`../`)||vc.test(t)?t:null}var bc=new hc({renderer:{html({text:e}){return _c(e)},link({href:e,title:t,tokens:n}){let r=this.parser.parseInline(n),i=yc(e);if(i===null)return r;let a=t?` title="${_c(t)}"`:``;return`<a href="${_c(i)}"${a}>${r}</a>`},image({href:e,title:t,text:n}){let r=yc(e);if(r===null)return _c(n);let i=t?` title="${_c(t)}"`:``;return`<img src="${_c(r)}" alt="${_c(n)}"${i}>`}}});function xc(e){return e===null||e.trim()===``?``:bc.parse(e)}var Sc={class:`text-sm text-muted-foreground`},Cc=[`title`,`innerHTML`],wc=L({__name:`NoteEditor`,props:{modelValue:{},readonly:{type:Boolean},translate:{type:Function}},emits:[`update:modelValue`],setup(e,{emit:t}){let n=e,r=t,i=P(!1),a=P(``),o=P(null);async function s(){n.readonly||(a.value=n.modelValue,i.value=!0,await hn(),o.value?.focus())}function c(){i.value=!1,a.value!==n.modelValue&&r(`update:modelValue`,a.value)}function l(){a.value=n.modelValue,i.value=!1}return(t,n)=>(U(),W(`div`,Sc,[i.value?On((U(),W(`textarea`,{key:0,ref_key:`input`,ref:o,"onUpdate:modelValue":n[0]||=e=>a.value=e,rows:`4`,class:`w-full resize-y rounded border border-border bg-background p-2 font-mono text-xs text-foreground outline-none focus:border-ring`,onBlur:n[1]||=e=>c(),onKeydown:n[2]||=lo(e=>l(),[`escape`])},null,544)),[[to,a.value]]):e.modelValue.trim()===``?e.readonly?q(``,!0):(U(),W(`button`,{key:2,type:`button`,class:`rounded border border-dashed border-border px-2 py-1 text-xs text-muted-foreground transition-colors hover:bg-muted/40`,onClick:n[4]||=e=>s()},O(e.translate(`docs.addNote`)),1)):(U(),W(`div`,{key:1,class:D([`leading-relaxed`,e.readonly?``:`cursor-text rounded transition-colors hover:bg-muted/30`]),title:e.readonly?void 0:e.translate(`docs.editNote`),onClick:n[3]||=e=>s(),innerHTML:F(xc)(e.modelValue)},null,10,Cc))]))}}),Tc={class:`flex flex-col gap-5`},Ec={class:`flex flex-col gap-2`},Dc={class:`flex flex-wrap items-center gap-2`},Oc={class:`font-mono text-lg font-semibold text-foreground`},kc={key:0,class:`rounded bg-muted/50 px-1.5 py-0.5 text-[10px] uppercase text-muted-foreground`},Ac={class:`mb-1.5 text-xs font-semibold uppercase tracking-wide text-muted-foreground`},jc={class:`flex flex-wrap gap-1`},Mc={class:`mb-1.5 text-xs font-semibold uppercase tracking-wide text-muted-foreground`},Nc={key:0,class:`text-xs text-muted-foreground`},Pc={key:1,class:`flex flex-col gap-1`},Fc=[`onClick`],Ic=L({__name:`EnumPage`,props:{enumType:{},snapshot:{},translate:{type:Function}},emits:[`select`],setup(e,{emit:t}){let n=e,r=t,i=Y(()=>n.enumType.schema?`${n.enumType.schema}.${n.enumType.name}`:n.enumType.name),a=Y(()=>Bo(n.snapshot,n.enumType.name));return(t,n)=>(U(),W(`article`,Tc,[G(`header`,Ec,[G(`div`,Dc,[G(`h2`,Oc,O(i.value),1),e.enumType.synthesized?(U(),W(`span`,kc,`synthesized`)):q(``,!0)]),K(wc,{"model-value":e.enumType.note??``,readonly:``,translate:e.translate},null,8,[`model-value`,`translate`])]),G(`section`,null,[G(`h3`,Ac,O(e.translate(`docs.enumValues`)),1),G(`ul`,jc,[(U(!0),W(V,null,R(e.enumType.values,e=>(U(),W(`li`,{key:e,class:`rounded bg-muted/50 px-1.5 py-0.5 font-mono text-[11px] text-foreground`},O(e),1))),128))])]),G(`section`,null,[G(`h3`,Mc,O(e.translate(`docs.usedBy`)),1),a.value.length===0?(U(),W(`p`,Nc,`No column uses this enum.`)):(U(),W(`ul`,Pc,[(U(!0),W(V,null,R(a.value,e=>(U(),W(`li`,{key:`${e.tableKey}.${e.column}`,class:`text-xs`},[G(`button`,{type:`button`,class:`w-full rounded border border-border bg-background px-2 py-1.5 text-left font-mono transition-colors hover:bg-muted/40`,onClick:t=>r(`select`,e.tableKey)},O(e.tableKey)+`.`+O(e.column),9,Fc)]))),128))]))])]))}}),Lc={class:`flex flex-col gap-3`},Rc={class:`flex flex-col gap-1`},zc={class:`text-[10px] uppercase tracking-wide text-muted-foreground`},Bc=[`value`,`placeholder`],Vc={class:`flex flex-col gap-2`},Hc={class:`text-[10px] uppercase tracking-wide text-muted-foreground`},Uc={class:`flex items-center gap-1.5`},Wc=[`t Line truncated
@@ -36,7 +36,7 @@
"apps/desktop/src/i18n/locales/docs/pt-BR.ts": "f92c0b95b1b807c60a5136677808ed5014d9061dffd970aa5866eb1c82300dc5", "apps/desktop/src/i18n/locales/docs/pt-BR.ts": "f92c0b95b1b807c60a5136677808ed5014d9061dffd970aa5866eb1c82300dc5",
"apps/desktop/src/i18n/locales/docs/zh-CN.ts": "2092c39277f2a6774405124d1f167bbcbc5f633d8f82bbd2b28ff5e12d78f3f7", "apps/desktop/src/i18n/locales/docs/zh-CN.ts": "2092c39277f2a6774405124d1f167bbcbc5f633d8f82bbd2b28ff5e12d78f3f7",
"apps/desktop/src/i18n/locales/docs/zh-TW.ts": "691cf502248dbd09358c6c276990945013b26c52fb682bcd56b26f378daea29c", "apps/desktop/src/i18n/locales/docs/zh-TW.ts": "691cf502248dbd09358c6c276990945013b26c52fb682bcd56b26f378daea29c",
"apps/desktop/src/lib/app/localeOptions.ts": "1149b12ccbcf012794bc2384636a54d3629fdb8f897924d58e0bce962d0a80b9", "apps/desktop/src/lib/app/localeOptions.ts": "2c19ecb7c91050d5f1c84c381606087ada11870d3ee95029362f84f34de23239",
"apps/desktop/src/lib/diagram/erDiagram.ts": "e28aa2b5fbba001ae78bc0c4218b11f93b0e14ab9f54562f14254386b98bad11", "apps/desktop/src/lib/diagram/erDiagram.ts": "e28aa2b5fbba001ae78bc0c4218b11f93b0e14ab9f54562f14254386b98bad11",
"apps/desktop/src/styles/tokens.css": "b8852ce50865ad98ebc992971f7a06670c5d830ca82efcee956f8d3eb7c2e9a3", "apps/desktop/src/styles/tokens.css": "b8852ce50865ad98ebc992971f7a06670c5d830ca82efcee956f8d3eb7c2e9a3",
"apps/desktop/tsconfig.json": "5ad521941835ad8529e9b81ba79c11650e5f020f0e376b7a9f17e22a9306fa76", "apps/desktop/tsconfig.json": "5ad521941835ad8529e9b81ba79c11650e5f020f0e376b7a9f17e22a9306fa76",
+2 -1
View File
@@ -2,6 +2,7 @@ import assert from "node:assert/strict";
import { test } from "vitest"; import { test } from "vitest";
import type { ComposerTranslation } from "vue-i18n"; import type { ComposerTranslation } from "vue-i18n";
import { translateBackendError } from "../../apps/desktop/src/i18n/backend-errors"; import { translateBackendError } from "../../apps/desktop/src/i18n/backend-errors";
import az from "../../apps/desktop/src/i18n/locales/az";
import en from "../../apps/desktop/src/i18n/locales/en"; import en from "../../apps/desktop/src/i18n/locales/en";
import es from "../../apps/desktop/src/i18n/locales/es"; import es from "../../apps/desktop/src/i18n/locales/es";
import it from "../../apps/desktop/src/i18n/locales/it"; import it from "../../apps/desktop/src/i18n/locales/it";
@@ -78,7 +79,7 @@ test("Claude Code CLI errors are localized while retaining their stable code and
}); });
test("every current locale defines all AI CLI diagnostic messages", () => { test("every current locale defines all AI CLI diagnostic messages", () => {
const locales = { en, es, it, ja, ko, ptBR, tr, zhCN, zhTW } as const; const locales = { az, en, es, it, ja, ko, ptBR, tr, zhCN, zhTW } as const;
for (const [localeName, locale] of Object.entries(locales)) { for (const [localeName, locale] of Object.entries(locales)) {
assert.equal(typeof locale.ai.requestFailed, "string", `${localeName}.ai.requestFailed`); assert.equal(typeof locale.ai.requestFailed, "string", `${localeName}.ai.requestFailed`);
+2 -1
View File
@@ -1,5 +1,6 @@
import { strict as assert } from "node:assert"; import { strict as assert } from "node:assert";
import { test } from "vitest"; import { test } from "vitest";
import az from "../../apps/desktop/src/i18n/locales/az.ts";
import en from "../../apps/desktop/src/i18n/locales/en.ts"; import en from "../../apps/desktop/src/i18n/locales/en.ts";
import es from "../../apps/desktop/src/i18n/locales/es.ts"; import es from "../../apps/desktop/src/i18n/locales/es.ts";
import it from "../../apps/desktop/src/i18n/locales/it.ts"; import it from "../../apps/desktop/src/i18n/locales/it.ts";
@@ -11,7 +12,7 @@ import zhCN from "../../apps/desktop/src/i18n/locales/zh-CN.ts";
import zhTW from "../../apps/desktop/src/i18n/locales/zh-TW.ts"; import zhTW from "../../apps/desktop/src/i18n/locales/zh-TW.ts";
test("every locale defines the PostgreSQL legacy TLS labels", () => { test("every locale defines the PostgreSQL legacy TLS labels", () => {
const locales = { en, es, it, ja, ko, ptBR, tr, zhCN, zhTW } as const; const locales = { az, en, es, it, ja, ko, ptBR, tr, zhCN, zhTW } as const;
for (const [localeName, locale] of Object.entries(locales)) { for (const [localeName, locale] of Object.entries(locales)) {
assert.ok(locale.connection.postgresLegacyTls.length > 0, `${localeName}: connection.postgresLegacyTls`); assert.ok(locale.connection.postgresLegacyTls.length > 0, `${localeName}: connection.postgresLegacyTls`);
+2 -1
View File
@@ -2,6 +2,7 @@ import assert from "node:assert/strict";
import { readFileSync } from "node:fs"; import { readFileSync } from "node:fs";
import { test } from "vitest"; import { test } from "vitest";
import { compileScript, compileTemplate, parse } from "vue/compiler-sfc"; import { compileScript, compileTemplate, parse } from "vue/compiler-sfc";
import az from "../../apps/desktop/src/i18n/locales/az.ts";
import en from "../../apps/desktop/src/i18n/locales/en.ts"; import en from "../../apps/desktop/src/i18n/locales/en.ts";
import es from "../../apps/desktop/src/i18n/locales/es.ts"; import es from "../../apps/desktop/src/i18n/locales/es.ts";
import it from "../../apps/desktop/src/i18n/locales/it.ts"; import it from "../../apps/desktop/src/i18n/locales/it.ts";
@@ -81,7 +82,7 @@ test("ContentArea wires server messages into the switcher and the messages view"
}); });
test("every locale defines the query message strings", () => { test("every locale defines the query message strings", () => {
const locales = { en, es, it, ja, ko, "pt-BR": ptBR, tr, "zh-CN": zhCN, "zh-TW": zhTW }; const locales = { az, en, es, it, ja, ko, "pt-BR": ptBR, tr, "zh-CN": zhCN, "zh-TW": zhTW };
for (const [name, locale] of Object.entries(locales)) { for (const [name, locale] of Object.entries(locales)) {
assert.ok(locale.queryMessages.empty.length > 0, `${name}: queryMessages.empty`); assert.ok(locale.queryMessages.empty.length > 0, `${name}: queryMessages.empty`);
+1 -1
View File
@@ -6,7 +6,7 @@ const runtimeHost = readFileSync("apps/desktop/src/components/sidebar/SidebarTre
const connectionMutationRuntime = readFileSync("apps/desktop/src/composables/useSidebarConnectionMutationRuntime.ts", "utf8"); const connectionMutationRuntime = readFileSync("apps/desktop/src/composables/useSidebarConnectionMutationRuntime.ts", "utf8");
const databaseSpecificMutationRuntime = readFileSync("apps/desktop/src/composables/useSidebarDatabaseSpecificMutationRuntime.ts", "utf8"); const databaseSpecificMutationRuntime = readFileSync("apps/desktop/src/composables/useSidebarDatabaseSpecificMutationRuntime.ts", "utf8");
const tableMutationRuntime = readFileSync("apps/desktop/src/composables/useSidebarTableMutationRuntime.ts", "utf8"); const tableMutationRuntime = readFileSync("apps/desktop/src/composables/useSidebarTableMutationRuntime.ts", "utf8");
const localeSources = Object.fromEntries(["en", "es", "it", "ja", "ko", "pt-BR", "tr", "zh-CN", "zh-TW"].map((locale) => [locale, readFileSync(`apps/desktop/src/i18n/locales/${locale}.ts`, "utf8")])); const localeSources = Object.fromEntries(["az", "en", "es", "it", "ja", "ko", "pt-BR", "tr", "zh-CN", "zh-TW"].map((locale) => [locale, readFileSync(`apps/desktop/src/i18n/locales/${locale}.ts`, "utf8")]));
function functionBody(name: string): string { function functionBody(name: string): string {
const source = [runtimeHost, connectionMutationRuntime, databaseSpecificMutationRuntime, tableMutationRuntime].find((candidate) => candidate.includes(`function ${name}(`)); const source = [runtimeHost, connectionMutationRuntime, databaseSpecificMutationRuntime, tableMutationRuntime].find((candidate) => candidate.includes(`function ${name}(`));
+9
View File
@@ -696,6 +696,7 @@ fn open_ai_config_deep_links(app: &tauri::AppHandle, links: Vec<String>) {
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum LocaleFamily { enum LocaleFamily {
Azerbaijani,
English, English,
SimplifiedChinese, SimplifiedChinese,
TraditionalChinese, TraditionalChinese,
@@ -726,6 +727,8 @@ fn locale_family(locale: &str) -> LocaleFamily {
LocaleFamily::Japanese LocaleFamily::Japanese
} else if is_language("ko") { } else if is_language("ko") {
LocaleFamily::Korean LocaleFamily::Korean
} else if is_language("az") {
LocaleFamily::Azerbaijani
} else if is_language("es") { } else if is_language("es") {
LocaleFamily::Spanish LocaleFamily::Spanish
} else if is_language("tr") { } else if is_language("tr") {
@@ -745,6 +748,7 @@ fn tray_menu_labels_for_locale(locale: &str) -> (&'static str, &'static str) {
LocaleFamily::TraditionalChinese => ("顯示 DBX", "退出 DBX"), LocaleFamily::TraditionalChinese => ("顯示 DBX", "退出 DBX"),
LocaleFamily::Japanese => ("DBXを表示", "DBXを終了"), LocaleFamily::Japanese => ("DBXを表示", "DBXを終了"),
LocaleFamily::Korean => ("DBX 표시", "DBX 종료"), LocaleFamily::Korean => ("DBX 표시", "DBX 종료"),
LocaleFamily::Azerbaijani => ("DBX-i göstər", "DBX-dən çıx"),
LocaleFamily::Spanish => ("Mostrar DBX", "Salir de DBX"), LocaleFamily::Spanish => ("Mostrar DBX", "Salir de DBX"),
LocaleFamily::Italian => ("Mostra DBX", "Esci da DBX"), LocaleFamily::Italian => ("Mostra DBX", "Esci da DBX"),
LocaleFamily::Turkish => ("DBX'i Göster", "DBX'ten Çık"), LocaleFamily::Turkish => ("DBX'i Göster", "DBX'ten Çık"),
@@ -761,6 +765,7 @@ fn app_menu_copy_support_info_label(locale: &str) -> &'static str {
LocaleFamily::TraditionalChinese => "複製支援資訊", LocaleFamily::TraditionalChinese => "複製支援資訊",
LocaleFamily::Japanese => "サポート情報をコピー", LocaleFamily::Japanese => "サポート情報をコピー",
LocaleFamily::Korean => "지원 정보 복사", LocaleFamily::Korean => "지원 정보 복사",
LocaleFamily::Azerbaijani => "Dəstək məlumatlarını kopyala",
LocaleFamily::Spanish => "Copiar información", LocaleFamily::Spanish => "Copiar información",
LocaleFamily::Italian => "Copia informazioni", LocaleFamily::Italian => "Copia informazioni",
LocaleFamily::Turkish => "Destek bilgilerini kopyala", LocaleFamily::Turkish => "Destek bilgilerini kopyala",
@@ -775,6 +780,7 @@ fn app_menu_quit_label(locale: &str, app_name: &str) -> String {
LocaleFamily::SimplifiedChinese | LocaleFamily::TraditionalChinese => format!("退出 {app_name}"), LocaleFamily::SimplifiedChinese | LocaleFamily::TraditionalChinese => format!("退出 {app_name}"),
LocaleFamily::Japanese => format!("{app_name}を終了"), LocaleFamily::Japanese => format!("{app_name}を終了"),
LocaleFamily::Korean => format!("{app_name} 종료"), LocaleFamily::Korean => format!("{app_name} 종료"),
LocaleFamily::Azerbaijani => format!("{app_name}-dən çıx"),
LocaleFamily::Spanish => format!("Salir de {app_name}"), LocaleFamily::Spanish => format!("Salir de {app_name}"),
LocaleFamily::Italian => format!("Esci da {app_name}"), LocaleFamily::Italian => format!("Esci da {app_name}"),
LocaleFamily::Turkish => format!("{app_name} Uygulamasından Çık"), LocaleFamily::Turkish => format!("{app_name} Uygulamasından Çık"),
@@ -985,6 +991,7 @@ mod tests {
assert_eq!(tray_menu_labels_for_locale("zh-MO"), ("顯示 DBX", "退出 DBX")); assert_eq!(tray_menu_labels_for_locale("zh-MO"), ("顯示 DBX", "退出 DBX"));
assert_eq!(tray_menu_labels_for_locale("ja-JP"), ("DBXを表示", "DBXを終了")); assert_eq!(tray_menu_labels_for_locale("ja-JP"), ("DBXを表示", "DBXを終了"));
assert_eq!(tray_menu_labels_for_locale("ko-KR"), ("DBX 표시", "DBX 종료")); assert_eq!(tray_menu_labels_for_locale("ko-KR"), ("DBX 표시", "DBX 종료"));
assert_eq!(tray_menu_labels_for_locale("az-AZ"), ("DBX-i göstər", "DBX-dən çıx"));
assert_eq!(tray_menu_labels_for_locale("es-ES"), ("Mostrar DBX", "Salir de DBX")); assert_eq!(tray_menu_labels_for_locale("es-ES"), ("Mostrar DBX", "Salir de DBX"));
assert_eq!(tray_menu_labels_for_locale("it-IT"), ("Mostra DBX", "Esci da DBX")); assert_eq!(tray_menu_labels_for_locale("it-IT"), ("Mostra DBX", "Esci da DBX"));
assert_eq!(tray_menu_labels_for_locale("pt-BR"), ("Mostrar DBX", "Sair do DBX")); assert_eq!(tray_menu_labels_for_locale("pt-BR"), ("Mostrar DBX", "Sair do DBX"));
@@ -1002,12 +1009,14 @@ mod tests {
assert_eq!(app_menu_quit_label("ja-JP", "DBX"), "DBXを終了"); assert_eq!(app_menu_quit_label("ja-JP", "DBX"), "DBXを終了");
assert_eq!(app_menu_quit_label("ko-KR", "DBX"), "DBX 종료"); assert_eq!(app_menu_quit_label("ko-KR", "DBX"), "DBX 종료");
assert_eq!(app_menu_quit_label("tr-TR", "DBX"), "DBX Uygulamasından Çık"); assert_eq!(app_menu_quit_label("tr-TR", "DBX"), "DBX Uygulamasından Çık");
assert_eq!(app_menu_quit_label("az-AZ", "DBX"), "DBX-dən çıx");
assert_eq!(app_menu_quit_label("en-US", "DBX"), "Quit DBX"); assert_eq!(app_menu_quit_label("en-US", "DBX"), "Quit DBX");
assert_eq!(app_menu_quit_label("", "DBX"), "Quit DBX"); assert_eq!(app_menu_quit_label("", "DBX"), "Quit DBX");
assert_eq!(app_menu_copy_support_info_label("zh-CN"), "复制支持信息"); assert_eq!(app_menu_copy_support_info_label("zh-CN"), "复制支持信息");
assert_eq!(app_menu_copy_support_info_label("zh-TW"), "複製支援資訊"); assert_eq!(app_menu_copy_support_info_label("zh-TW"), "複製支援資訊");
assert_eq!(app_menu_copy_support_info_label("ko-KR"), "지원 정보 복사"); assert_eq!(app_menu_copy_support_info_label("ko-KR"), "지원 정보 복사");
assert_eq!(app_menu_copy_support_info_label("tr-TR"), "Destek bilgilerini kopyala"); assert_eq!(app_menu_copy_support_info_label("tr-TR"), "Destek bilgilerini kopyala");
assert_eq!(app_menu_copy_support_info_label("az-AZ"), "Dəstək məlumatlarını kopyala");
assert_eq!(app_menu_copy_support_info_label("en-US"), "Copy Support Info"); assert_eq!(app_menu_copy_support_info_label("en-US"), "Copy Support Info");
} }