From ef93f040b0a99eeae8c3dcc3dc03785d08c01821 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 5 Nov 2026 19:46:37 +0000 Subject: [PATCH] i18n(service-storage): ship the file and upload-session objects in zh-Hant, ar, fr, pt-BR, ru, de and ko Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01Utp6Cai5CRdAs4u9gTipWU --- .changeset/30512-service-storage-locales.md | 10 + .../scripts/i18n-extract.config.ts | 16 +- .../src/translations/ar.objects.generated.ts | 182 ++++++++++++++++++ .../ar.source-hashes.generated.ts | 22 +++ .../src/translations/de.objects.generated.ts | 182 ++++++++++++++++++ .../de.source-hashes.generated.ts | 26 +++ .../src/translations/fr.objects.generated.ts | 182 ++++++++++++++++++ .../fr.source-hashes.generated.ts | 22 +++ .../service-storage/src/translations/index.ts | 21 ++ .../src/translations/ko.objects.generated.ts | 182 ++++++++++++++++++ .../ko.source-hashes.generated.ts | 22 +++ .../translations/pt-BR.objects.generated.ts | 182 ++++++++++++++++++ .../pt-BR.source-hashes.generated.ts | 26 +++ .../src/translations/ru.objects.generated.ts | 182 ++++++++++++++++++ .../ru.source-hashes.generated.ts | 22 +++ .../translations/zh-Hant.objects.generated.ts | 182 ++++++++++++++++++ .../zh-Hant.source-hashes.generated.ts | 22 +++ 17 files changed, 1482 insertions(+), 1 deletion(-) create mode 100644 .changeset/30512-service-storage-locales.md create mode 100644 packages/services/service-storage/src/translations/ar.objects.generated.ts create mode 100644 packages/services/service-storage/src/translations/ar.source-hashes.generated.ts create mode 100644 packages/services/service-storage/src/translations/de.objects.generated.ts create mode 100644 packages/services/service-storage/src/translations/de.source-hashes.generated.ts create mode 100644 packages/services/service-storage/src/translations/fr.objects.generated.ts create mode 100644 packages/services/service-storage/src/translations/fr.source-hashes.generated.ts create mode 100644 packages/services/service-storage/src/translations/ko.objects.generated.ts create mode 100644 packages/services/service-storage/src/translations/ko.source-hashes.generated.ts create mode 100644 packages/services/service-storage/src/translations/pt-BR.objects.generated.ts create mode 100644 packages/services/service-storage/src/translations/pt-BR.source-hashes.generated.ts create mode 100644 packages/services/service-storage/src/translations/ru.objects.generated.ts create mode 100644 packages/services/service-storage/src/translations/ru.source-hashes.generated.ts create mode 100644 packages/services/service-storage/src/translations/zh-Hant.objects.generated.ts create mode 100644 packages/services/service-storage/src/translations/zh-Hant.source-hashes.generated.ts diff --git a/.changeset/30512-service-storage-locales.md b/.changeset/30512-service-storage-locales.md new file mode 100644 index 00000000000..1ec6f03f9a7 --- /dev/null +++ b/.changeset/30512-service-storage-locales.md @@ -0,0 +1,10 @@ +--- +'@objectstack/service-storage': patch +--- + +i18n(service-storage): the file and upload-session objects ship in all eleven platform languages + +Clause-②: no +Metadata-protocol: none + +`sys_file` and `sys_upload_session` now carry Traditional Chinese (`zh-Hant`), Arabic (`ar`), French (`fr`), Brazilian Portuguese (`pt-BR`), Russian (`ru`), German (`de`) and Korean (`ko`) beside the existing `en`, `zh-CN`, `ja-JP` and `es-ES`, so a reader in one of those languages sees the file and upload screens in their own language instead of English. Each new locale is registered under its platform-table tag with its source-hash companion, and the package's extract command lists the seven tags, so the existing `check:i18n` bundle check covers them. Package 10 of #30512. diff --git a/packages/services/service-storage/scripts/i18n-extract.config.ts b/packages/services/service-storage/scripts/i18n-extract.config.ts index aeea76ab3eb..b6e2a217d69 100644 --- a/packages/services/service-storage/scripts/i18n-extract.config.ts +++ b/packages/services/service-storage/scripts/i18n-extract.config.ts @@ -11,7 +11,7 @@ * decomposition (see that package's extract config). * * os i18n extract packages/services/service-storage/scripts/i18n-extract.config.ts \ - * --locales=zh-CN,ja-JP,es-ES --fill=default --objects-only --no-metadata-forms \ + * --locales=zh-CN,ja-JP,es-ES,zh-Hant,ar,fr,pt-BR,ru,de,ko --fill=default --objects-only --no-metadata-forms \ * --source-hashes \ * --out=packages/services/service-storage/src/translations * @@ -45,6 +45,13 @@ import { enObjects } from '../src/translations/en.objects.generated.js'; import { zhCNObjects } from '../src/translations/zh-CN.objects.generated.js'; import { jaJPObjects } from '../src/translations/ja-JP.objects.generated.js'; import { esESObjects } from '../src/translations/es-ES.objects.generated.js'; +import { zhHantObjects } from '../src/translations/zh-Hant.objects.generated.js'; +import { arObjects } from '../src/translations/ar.objects.generated.js'; +import { frObjects } from '../src/translations/fr.objects.generated.js'; +import { ptBRObjects } from '../src/translations/pt-BR.objects.generated.js'; +import { ruObjects } from '../src/translations/ru.objects.generated.js'; +import { deObjects } from '../src/translations/de.objects.generated.js'; +import { koObjects } from '../src/translations/ko.objects.generated.js'; /** * The annotation is load-bearing, not decoration (#10868). `defineStack` @@ -67,6 +74,13 @@ const config: ObjectStackDefinition = defineStack({ { 'zh-CN': { objects: zhCNObjects } }, { 'ja-JP': { objects: jaJPObjects } }, { 'es-ES': { objects: esESObjects } }, + { 'zh-Hant': { objects: zhHantObjects } }, + { 'ar': { objects: arObjects } }, + { 'fr': { objects: frObjects } }, + { 'pt-BR': { objects: ptBRObjects } }, + { 'ru': { objects: ruObjects } }, + { 'de': { objects: deObjects } }, + { 'ko': { objects: koObjects } }, ], }); diff --git a/packages/services/service-storage/src/translations/ar.objects.generated.ts b/packages/services/service-storage/src/translations/ar.objects.generated.ts new file mode 100644 index 00000000000..b44f6c5a16d --- /dev/null +++ b/packages/services/service-storage/src/translations/ar.objects.generated.ts @@ -0,0 +1,182 @@ +// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license. + +/** + * Auto-generated by 'os i18n extract' for locale 'ar'. + * Edit translations in place; re-run extract (with --merge) to fill new gaps. + * Do not hand-edit the structure — only the leaf string values. + * Merge only fills gaps: correcting a source label/description does not + * push the correction into a leaf here that already holds a translation — + * a present-but-stale string is not a gap, so it is left as-is. Re-translate + * it by hand when its source changes; nothing here or in `os i18n check` + * tells a leaf a translator updated on purpose from one nobody has looked + * at since the source moved. + */ + +import type { TranslationData } from '@objectstack/spec/system'; + +export const arObjects: NonNullable = { + sys_file: { + label: "ملف النظام", + pluralLabel: "ملفات النظام", + description: "البيانات الوصفية لملفات خدمة التخزين (ربط fileId ↔ key)", + fields: { + id: { + label: "معرّف الملف" + }, + key: { + label: "مفتاح التخزين" + }, + name: { + label: "اسم الملف" + }, + mime_type: { + label: "نوع MIME" + }, + size: { + label: "الحجم (بايت)" + }, + scope: { + label: "النطاق", + options: { + user: "المستخدم", + tenant: "المستأجر", + private: "خاص", + temp: "مؤقت", + attachments: "المرفقات" + } + }, + bucket: { + label: "الحاوية" + }, + acl: { + label: "قائمة التحكم بالوصول", + options: { + private: "خاص", + public_read: "قراءة عامة" + } + }, + status: { + label: "الحالة", + options: { + pending: "بانتظار الرفع", + committed: "مُثبَّت", + deleted: "محذوف" + } + }, + etag: { + label: "ETag" + }, + owner_id: { + label: "معرّف المالك", + help: "المستخدم الذي رفع الملف (صفة التأليف، لا مالك مرجع الحقل)" + }, + ref_object: { + label: "الكائن المُشير", + help: "الاسم المختصر لكائن السجل الذي يملك حقلُه هذا الملف" + }, + ref_id: { + label: "السجل المُشير", + help: "المفتاح الأساسي للسجل الذي يملك حقلُه هذا الملف" + }, + ref_field: { + label: "الحقل المُشير", + help: "اسم الحقل في السجل المالك الذي يحمل معرّف هذا الملف" + }, + released_ref_object: { + label: "الكائن الذي حُرِّر منه", + help: "الاسم المختصر لكائن السجل الذي امتلك هذا الملف آخر مرة، بعد أن تخلّى عنه" + }, + released_ref_id: { + label: "السجل الذي حُرِّر منه", + help: "المفتاح الأساسي للسجل الذي امتلك هذا الملف آخر مرة، بعد أن تخلّى عنه" + }, + metadata: { + label: "البيانات الوصفية (JSON)" + }, + created_at: { + label: "تاريخ الإنشاء" + }, + updated_at: { + label: "تاريخ التحديث" + }, + deleted_at: { + label: "تاريخ الحذف", + help: "طابع زمني للشاهد — يُضبط عند إزالة آخر مرجع sys_attachment لملف في نطاق المرفقات؛ وبعد انقضاء فترة السماح يستردّ TTL دورة الحياة الصف (وبايتات تخزينه، عبر حارس الاسترداد في sys_file). قيمته NULL للصفوف الحيّة." + } + } + }, + sys_upload_session: { + label: "جلسة رفع النظام", + pluralLabel: "جلسات رفع النظام", + description: "جلسات رفع متعدد الأجزاء قابلة للاستئناف تتتبّعها service-storage", + fields: { + id: { + label: "معرّف جلسة الرفع" + }, + file_id: { + label: "معرّف الملف" + }, + key: { + label: "مفتاح التخزين" + }, + filename: { + label: "اسم الملف" + }, + mime_type: { + label: "نوع MIME" + }, + total_size: { + label: "الحجم الإجمالي (بايت)" + }, + chunk_size: { + label: "حجم الجزء (بايت)" + }, + total_chunks: { + label: "إجمالي الأجزاء" + }, + uploaded_chunks: { + label: "الأجزاء المرفوعة" + }, + uploaded_size: { + label: "الحجم المرفوع (بايت)" + }, + parts: { + label: "الأجزاء المرفوعة (JSON)" + }, + resume_token: { + label: "رمز الاستئناف" + }, + backend_upload_id: { + label: "معرّف الرفع في الخلفية" + }, + scope: { + label: "النطاق" + }, + bucket: { + label: "الحاوية" + }, + metadata: { + label: "البيانات الوصفية (JSON)" + }, + status: { + label: "الحالة", + options: { + in_progress: "قيد التنفيذ", + completing: "جارٍ الإكمال", + completed: "مكتمل", + failed: "فشل", + expired: "منتهي الصلاحية" + } + }, + started_at: { + label: "وقت البدء" + }, + expires_at: { + label: "وقت الانتهاء" + }, + updated_at: { + label: "تاريخ التحديث" + } + } + } +}; diff --git a/packages/services/service-storage/src/translations/ar.source-hashes.generated.ts b/packages/services/service-storage/src/translations/ar.source-hashes.generated.ts new file mode 100644 index 00000000000..a17d19af603 --- /dev/null +++ b/packages/services/service-storage/src/translations/ar.source-hashes.generated.ts @@ -0,0 +1,22 @@ +// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. + +/** + * Auto-generated by 'os i18n extract' for locale 'ar'. Do not hand-edit. + * + * Each entry is the digest of the SOURCE REVISION that this locale's leaf at + * that path is still a byte copy of — provenance for the generated half of the + * bundles (commit 09b4f4e4e): a leaf whose digest no longer matches its source is stale and serves the source text instead. + * + * An entry exists only while the leaf IS such a copy. Re-translate the leaf in + * `.objects.generated.ts` and the next extract drops its entry by + * itself — the table makes no claim about text a translator wrote. A path with + * no entry is LEGACY-TRUSTED and never reported stale. + * + * ⚠️ Do not "fix" a staleness report by editing this file. Refreshing a digest + * records that the current text was copied from the current source, which is + * the false claim the mechanism exists to detect. Fix the TRANSLATION. + */ + +export const arGeneratedSourceHashes: Readonly> = { + "objects.sys_file.fields.etag.label": "a62e7fe0bac46fcb", +}; diff --git a/packages/services/service-storage/src/translations/de.objects.generated.ts b/packages/services/service-storage/src/translations/de.objects.generated.ts new file mode 100644 index 00000000000..f268f942c2a --- /dev/null +++ b/packages/services/service-storage/src/translations/de.objects.generated.ts @@ -0,0 +1,182 @@ +// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license. + +/** + * Auto-generated by 'os i18n extract' for locale 'de'. + * Edit translations in place; re-run extract (with --merge) to fill new gaps. + * Do not hand-edit the structure — only the leaf string values. + * Merge only fills gaps: correcting a source label/description does not + * push the correction into a leaf here that already holds a translation — + * a present-but-stale string is not a gap, so it is left as-is. Re-translate + * it by hand when its source changes; nothing here or in `os i18n check` + * tells a leaf a translator updated on purpose from one nobody has looked + * at since the source moved. + */ + +import type { TranslationData } from '@objectstack/spec/system'; + +export const deObjects: NonNullable = { + sys_file: { + label: "Systemdatei", + pluralLabel: "Systemdateien", + description: "Dateimetadaten des Speicherdienstes (Zuordnung fileId ↔ key)", + fields: { + id: { + label: "Datei-ID" + }, + key: { + label: "Speicherschlüssel" + }, + name: { + label: "Dateiname" + }, + mime_type: { + label: "MIME-Typ" + }, + size: { + label: "Größe (Bytes)" + }, + scope: { + label: "Bereich", + options: { + user: "Benutzer", + tenant: "Mandant", + private: "Privat", + temp: "Temporär", + attachments: "Anhänge" + } + }, + bucket: { + label: "Bucket" + }, + acl: { + label: "Zugriffssteuerung", + options: { + private: "Privat", + public_read: "Öffentlich lesbar" + } + }, + status: { + label: "Status", + options: { + pending: "Upload ausstehend", + committed: "Festgeschrieben", + deleted: "Gelöscht" + } + }, + etag: { + label: "ETag" + }, + owner_id: { + label: "Eigentümer-ID", + help: "Benutzer, der die Datei hochgeladen hat (Urheberschaft, nicht der Eigentümer der Feldreferenz)" + }, + ref_object: { + label: "Verweisendes Objekt", + help: "Kurzname des Objekts des Datensatzes, dessen Feld diese Datei besitzt" + }, + ref_id: { + label: "Verweisender Datensatz", + help: "Primärschlüssel des Datensatzes, dessen Feld diese Datei besitzt" + }, + ref_field: { + label: "Verweisendes Feld", + help: "Name des Felds im besitzenden Datensatz, das diese Datei-ID enthält" + }, + released_ref_object: { + label: "Freigegeben von Objekt", + help: "Kurzname des Objekts des Datensatzes, der diese Datei zuletzt besaß, nachdem er sie freigegeben hat" + }, + released_ref_id: { + label: "Freigegeben von Datensatz", + help: "Primärschlüssel des Datensatzes, der diese Datei zuletzt besaß, nachdem er sie freigegeben hat" + }, + metadata: { + label: "Metadaten (JSON)" + }, + created_at: { + label: "Erstellt am" + }, + updated_at: { + label: "Aktualisiert am" + }, + deleted_at: { + label: "Gelöscht am", + help: "Tombstone-Zeitstempel — wird gesetzt, wenn die letzte sys_attachment-Referenz auf eine Datei im Bereich attachments entfernt wird; die Lebenszyklus-TTL entfernt die Zeile (und ihre gespeicherten Bytes, über die Bereinigungssperre von sys_file) nach der Karenzzeit. NULL für aktive Zeilen." + } + } + }, + sys_upload_session: { + label: "System-Upload-Sitzung", + pluralLabel: "System-Upload-Sitzungen", + description: "Fortsetzbare Multipart-Upload-Sitzungen, die service-storage verfolgt", + fields: { + id: { + label: "Upload-Sitzungs-ID" + }, + file_id: { + label: "Datei-ID" + }, + key: { + label: "Speicherschlüssel" + }, + filename: { + label: "Dateiname" + }, + mime_type: { + label: "MIME-Typ" + }, + total_size: { + label: "Gesamtgröße (Bytes)" + }, + chunk_size: { + label: "Blockgröße (Bytes)" + }, + total_chunks: { + label: "Blöcke gesamt" + }, + uploaded_chunks: { + label: "Hochgeladene Blöcke" + }, + uploaded_size: { + label: "Hochgeladene Größe (Bytes)" + }, + parts: { + label: "Hochgeladene Teile (JSON)" + }, + resume_token: { + label: "Fortsetzungstoken" + }, + backend_upload_id: { + label: "Backend-Upload-ID" + }, + scope: { + label: "Bereich" + }, + bucket: { + label: "Bucket" + }, + metadata: { + label: "Metadaten (JSON)" + }, + status: { + label: "Status", + options: { + in_progress: "Läuft", + completing: "Wird abgeschlossen", + completed: "Abgeschlossen", + failed: "Fehlgeschlagen", + expired: "Abgelaufen" + } + }, + started_at: { + label: "Gestartet am" + }, + expires_at: { + label: "Läuft ab am" + }, + updated_at: { + label: "Aktualisiert am" + } + } + } +}; diff --git a/packages/services/service-storage/src/translations/de.source-hashes.generated.ts b/packages/services/service-storage/src/translations/de.source-hashes.generated.ts new file mode 100644 index 00000000000..dfdf20e5d8b --- /dev/null +++ b/packages/services/service-storage/src/translations/de.source-hashes.generated.ts @@ -0,0 +1,26 @@ +// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. + +/** + * Auto-generated by 'os i18n extract' for locale 'de'. Do not hand-edit. + * + * Each entry is the digest of the SOURCE REVISION that this locale's leaf at + * that path is still a byte copy of — provenance for the generated half of the + * bundles (commit 09b4f4e4e): a leaf whose digest no longer matches its source is stale and serves the source text instead. + * + * An entry exists only while the leaf IS such a copy. Re-translate the leaf in + * `.objects.generated.ts` and the next extract drops its entry by + * itself — the table makes no claim about text a translator wrote. A path with + * no entry is LEGACY-TRUSTED and never reported stale. + * + * ⚠️ Do not "fix" a staleness report by editing this file. Refreshing a digest + * records that the current text was copied from the current source, which is + * the false claim the mechanism exists to detect. Fix the TRANSLATION. + */ + +export const deGeneratedSourceHashes: Readonly> = { + "objects.sys_file.fields.bucket.label": "3aa22e888d1f90c0", + "objects.sys_file.fields.etag.label": "a62e7fe0bac46fcb", + "objects.sys_file.fields.status.label": "64a420165247654b", + "objects.sys_upload_session.fields.bucket.label": "3aa22e888d1f90c0", + "objects.sys_upload_session.fields.status.label": "64a420165247654b", +}; diff --git a/packages/services/service-storage/src/translations/fr.objects.generated.ts b/packages/services/service-storage/src/translations/fr.objects.generated.ts new file mode 100644 index 00000000000..290e5ce150b --- /dev/null +++ b/packages/services/service-storage/src/translations/fr.objects.generated.ts @@ -0,0 +1,182 @@ +// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license. + +/** + * Auto-generated by 'os i18n extract' for locale 'fr'. + * Edit translations in place; re-run extract (with --merge) to fill new gaps. + * Do not hand-edit the structure — only the leaf string values. + * Merge only fills gaps: correcting a source label/description does not + * push the correction into a leaf here that already holds a translation — + * a present-but-stale string is not a gap, so it is left as-is. Re-translate + * it by hand when its source changes; nothing here or in `os i18n check` + * tells a leaf a translator updated on purpose from one nobody has looked + * at since the source moved. + */ + +import type { TranslationData } from '@objectstack/spec/system'; + +export const frObjects: NonNullable = { + sys_file: { + label: "Fichier système", + pluralLabel: "Fichiers système", + description: "Métadonnées des fichiers du service de stockage (correspondance fileId ↔ key)", + fields: { + id: { + label: "ID du fichier" + }, + key: { + label: "Clé de stockage" + }, + name: { + label: "Nom du fichier" + }, + mime_type: { + label: "Type MIME" + }, + size: { + label: "Taille (octets)" + }, + scope: { + label: "Portée", + options: { + user: "Utilisateur", + tenant: "Locataire", + private: "Privé", + temp: "Temporaire", + attachments: "Pièces jointes" + } + }, + bucket: { + label: "Compartiment" + }, + acl: { + label: "Contrôle d’accès", + options: { + private: "Privé", + public_read: "Lecture publique" + } + }, + status: { + label: "Statut", + options: { + pending: "Téléversement en attente", + committed: "Validé", + deleted: "Supprimé" + } + }, + etag: { + label: "ETag" + }, + owner_id: { + label: "ID du propriétaire", + help: "Utilisateur qui a téléversé le fichier (auteur, pas le propriétaire de la référence de champ)" + }, + ref_object: { + label: "Objet référent", + help: "Nom court de l’objet de l’enregistrement dont un champ possède ce fichier" + }, + ref_id: { + label: "Enregistrement référent", + help: "Clé primaire de l’enregistrement dont un champ possède ce fichier" + }, + ref_field: { + label: "Champ référent", + help: "Nom du champ de l’enregistrement propriétaire qui contient l’identifiant de ce fichier" + }, + released_ref_object: { + label: "Objet de libération", + help: "Nom court de l’objet de l’enregistrement qui possédait ce fichier en dernier, après l’avoir libéré" + }, + released_ref_id: { + label: "Enregistrement de libération", + help: "Clé primaire de l’enregistrement qui possédait ce fichier en dernier, après l’avoir libéré" + }, + metadata: { + label: "Métadonnées (JSON)" + }, + created_at: { + label: "Créé le" + }, + updated_at: { + label: "Mis à jour le" + }, + deleted_at: { + label: "Supprimé le", + help: "Horodatage de pierre tombale — défini quand la dernière référence sys_attachment à un fichier de portée attachments est retirée ; le TTL du cycle de vie récupère la ligne (et ses octets stockés, via la garde de récupération de sys_file) après le délai de grâce. NULL pour les lignes actives." + } + } + }, + sys_upload_session: { + label: "Session de téléversement système", + pluralLabel: "Sessions de téléversement système", + description: "Sessions de téléversement multipart reprenables suivies par service-storage", + fields: { + id: { + label: "ID de session de téléversement" + }, + file_id: { + label: "ID du fichier" + }, + key: { + label: "Clé de stockage" + }, + filename: { + label: "Nom du fichier" + }, + mime_type: { + label: "Type MIME" + }, + total_size: { + label: "Taille totale (octets)" + }, + chunk_size: { + label: "Taille de bloc (octets)" + }, + total_chunks: { + label: "Nombre total de blocs" + }, + uploaded_chunks: { + label: "Blocs téléversés" + }, + uploaded_size: { + label: "Taille téléversée (octets)" + }, + parts: { + label: "Parties téléversées (JSON)" + }, + resume_token: { + label: "Jeton de reprise" + }, + backend_upload_id: { + label: "ID de téléversement du backend" + }, + scope: { + label: "Portée" + }, + bucket: { + label: "Compartiment" + }, + metadata: { + label: "Métadonnées (JSON)" + }, + status: { + label: "Statut", + options: { + in_progress: "En cours", + completing: "Finalisation", + completed: "Terminé", + failed: "Échec", + expired: "Expiré" + } + }, + started_at: { + label: "Commencé le" + }, + expires_at: { + label: "Expire le" + }, + updated_at: { + label: "Mis à jour le" + } + } + } +}; diff --git a/packages/services/service-storage/src/translations/fr.source-hashes.generated.ts b/packages/services/service-storage/src/translations/fr.source-hashes.generated.ts new file mode 100644 index 00000000000..0a635cf1136 --- /dev/null +++ b/packages/services/service-storage/src/translations/fr.source-hashes.generated.ts @@ -0,0 +1,22 @@ +// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. + +/** + * Auto-generated by 'os i18n extract' for locale 'fr'. Do not hand-edit. + * + * Each entry is the digest of the SOURCE REVISION that this locale's leaf at + * that path is still a byte copy of — provenance for the generated half of the + * bundles (commit 09b4f4e4e): a leaf whose digest no longer matches its source is stale and serves the source text instead. + * + * An entry exists only while the leaf IS such a copy. Re-translate the leaf in + * `.objects.generated.ts` and the next extract drops its entry by + * itself — the table makes no claim about text a translator wrote. A path with + * no entry is LEGACY-TRUSTED and never reported stale. + * + * ⚠️ Do not "fix" a staleness report by editing this file. Refreshing a digest + * records that the current text was copied from the current source, which is + * the false claim the mechanism exists to detect. Fix the TRANSLATION. + */ + +export const frGeneratedSourceHashes: Readonly> = { + "objects.sys_file.fields.etag.label": "a62e7fe0bac46fcb", +}; diff --git a/packages/services/service-storage/src/translations/index.ts b/packages/services/service-storage/src/translations/index.ts index 22621115880..aa439c66f6f 100644 --- a/packages/services/service-storage/src/translations/index.ts +++ b/packages/services/service-storage/src/translations/index.ts @@ -18,9 +18,23 @@ import { enObjects } from './en.objects.generated.js'; import { zhCNObjects } from './zh-CN.objects.generated.js'; import { jaJPObjects } from './ja-JP.objects.generated.js'; import { esESObjects } from './es-ES.objects.generated.js'; +import { zhHantObjects } from './zh-Hant.objects.generated.js'; +import { arObjects } from './ar.objects.generated.js'; +import { frObjects } from './fr.objects.generated.js'; +import { ptBRObjects } from './pt-BR.objects.generated.js'; +import { ruObjects } from './ru.objects.generated.js'; +import { deObjects } from './de.objects.generated.js'; +import { koObjects } from './ko.objects.generated.js'; import { zhCNGeneratedSourceHashes } from './zh-CN.source-hashes.generated.js'; import { jaJPGeneratedSourceHashes } from './ja-JP.source-hashes.generated.js'; import { esESGeneratedSourceHashes } from './es-ES.source-hashes.generated.js'; +import { zhHantGeneratedSourceHashes } from './zh-Hant.source-hashes.generated.js'; +import { arGeneratedSourceHashes } from './ar.source-hashes.generated.js'; +import { frGeneratedSourceHashes } from './fr.source-hashes.generated.js'; +import { ptBRGeneratedSourceHashes } from './pt-BR.source-hashes.generated.js'; +import { ruGeneratedSourceHashes } from './ru.source-hashes.generated.js'; +import { deGeneratedSourceHashes } from './de.source-hashes.generated.js'; +import { koGeneratedSourceHashes } from './ko.source-hashes.generated.js'; /** * ## The provenance companions are READ here, not merely recorded @@ -56,4 +70,11 @@ export const StorageTranslations: TranslationBundle = { 'zh-CN': withSourceFallback({ objects: zhCNObjects }, enSource, undefined, zhCNGeneratedSourceHashes), 'ja-JP': withSourceFallback({ objects: jaJPObjects }, enSource, undefined, jaJPGeneratedSourceHashes), 'es-ES': withSourceFallback({ objects: esESObjects }, enSource, undefined, esESGeneratedSourceHashes), + 'zh-Hant': withSourceFallback({ objects: zhHantObjects }, enSource, undefined, zhHantGeneratedSourceHashes), + 'ar': withSourceFallback({ objects: arObjects }, enSource, undefined, arGeneratedSourceHashes), + 'fr': withSourceFallback({ objects: frObjects }, enSource, undefined, frGeneratedSourceHashes), + 'pt-BR': withSourceFallback({ objects: ptBRObjects }, enSource, undefined, ptBRGeneratedSourceHashes), + 'ru': withSourceFallback({ objects: ruObjects }, enSource, undefined, ruGeneratedSourceHashes), + 'de': withSourceFallback({ objects: deObjects }, enSource, undefined, deGeneratedSourceHashes), + 'ko': withSourceFallback({ objects: koObjects }, enSource, undefined, koGeneratedSourceHashes), }; diff --git a/packages/services/service-storage/src/translations/ko.objects.generated.ts b/packages/services/service-storage/src/translations/ko.objects.generated.ts new file mode 100644 index 00000000000..56895c45d72 --- /dev/null +++ b/packages/services/service-storage/src/translations/ko.objects.generated.ts @@ -0,0 +1,182 @@ +// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license. + +/** + * Auto-generated by 'os i18n extract' for locale 'ko'. + * Edit translations in place; re-run extract (with --merge) to fill new gaps. + * Do not hand-edit the structure — only the leaf string values. + * Merge only fills gaps: correcting a source label/description does not + * push the correction into a leaf here that already holds a translation — + * a present-but-stale string is not a gap, so it is left as-is. Re-translate + * it by hand when its source changes; nothing here or in `os i18n check` + * tells a leaf a translator updated on purpose from one nobody has looked + * at since the source moved. + */ + +import type { TranslationData } from '@objectstack/spec/system'; + +export const koObjects: NonNullable = { + sys_file: { + label: "시스템 파일", + pluralLabel: "시스템 파일", + description: "스토리지 서비스 파일 메타데이터(fileId ↔ key 매핑)", + fields: { + id: { + label: "파일 ID" + }, + key: { + label: "스토리지 키" + }, + name: { + label: "파일 이름" + }, + mime_type: { + label: "MIME 유형" + }, + size: { + label: "크기(바이트)" + }, + scope: { + label: "범위", + options: { + user: "사용자", + tenant: "테넌트", + private: "비공개", + temp: "임시", + attachments: "첨부 파일" + } + }, + bucket: { + label: "버킷" + }, + acl: { + label: "액세스 제어", + options: { + private: "비공개", + public_read: "공개 읽기" + } + }, + status: { + label: "상태", + options: { + pending: "업로드 대기", + committed: "커밋됨", + deleted: "삭제됨" + } + }, + etag: { + label: "ETag" + }, + owner_id: { + label: "소유자 ID", + help: "파일을 업로드한 사용자(작성자이며, 필드 참조의 소유자가 아님)" + }, + ref_object: { + label: "참조하는 개체", + help: "이 파일을 소유한 필드가 있는 레코드의 개체 짧은 이름" + }, + ref_id: { + label: "참조하는 레코드", + help: "이 파일을 소유한 필드가 있는 레코드의 기본 키" + }, + ref_field: { + label: "참조하는 필드", + help: "이 파일 ID를 담고 있는 소유 레코드의 필드 이름" + }, + released_ref_object: { + label: "해제한 개체", + help: "이 파일을 마지막으로 소유했다가 해제한 레코드의 개체 짧은 이름" + }, + released_ref_id: { + label: "해제한 레코드", + help: "이 파일을 마지막으로 소유했다가 해제한 레코드의 기본 키" + }, + metadata: { + label: "메타데이터(JSON)" + }, + created_at: { + label: "생성 일시" + }, + updated_at: { + label: "수정 일시" + }, + deleted_at: { + label: "삭제 일시", + help: "툼스톤 타임스탬프 — attachments 범위 파일에 대한 마지막 sys_attachment 참조가 제거될 때 설정됩니다. 유예 기간이 지나면 수명 주기 TTL이 행(및 sys_file 회수 가드를 통해 저장된 바이트)을 회수합니다. 활성 행은 NULL입니다." + } + } + }, + sys_upload_session: { + label: "시스템 업로드 세션", + pluralLabel: "시스템 업로드 세션", + description: "service-storage가 추적하는 재개 가능한 멀티파트 업로드 세션", + fields: { + id: { + label: "업로드 세션 ID" + }, + file_id: { + label: "파일 ID" + }, + key: { + label: "스토리지 키" + }, + filename: { + label: "파일 이름" + }, + mime_type: { + label: "MIME 유형" + }, + total_size: { + label: "전체 크기(바이트)" + }, + chunk_size: { + label: "청크 크기(바이트)" + }, + total_chunks: { + label: "전체 청크 수" + }, + uploaded_chunks: { + label: "업로드된 청크 수" + }, + uploaded_size: { + label: "업로드된 크기(바이트)" + }, + parts: { + label: "업로드된 파트(JSON)" + }, + resume_token: { + label: "재개 토큰" + }, + backend_upload_id: { + label: "백엔드 업로드 ID" + }, + scope: { + label: "범위" + }, + bucket: { + label: "버킷" + }, + metadata: { + label: "메타데이터(JSON)" + }, + status: { + label: "상태", + options: { + in_progress: "진행 중", + completing: "완료 중", + completed: "완료됨", + failed: "실패", + expired: "만료됨" + } + }, + started_at: { + label: "시작 일시" + }, + expires_at: { + label: "만료 일시" + }, + updated_at: { + label: "수정 일시" + } + } + } +}; diff --git a/packages/services/service-storage/src/translations/ko.source-hashes.generated.ts b/packages/services/service-storage/src/translations/ko.source-hashes.generated.ts new file mode 100644 index 00000000000..5b4dbd4375f --- /dev/null +++ b/packages/services/service-storage/src/translations/ko.source-hashes.generated.ts @@ -0,0 +1,22 @@ +// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. + +/** + * Auto-generated by 'os i18n extract' for locale 'ko'. Do not hand-edit. + * + * Each entry is the digest of the SOURCE REVISION that this locale's leaf at + * that path is still a byte copy of — provenance for the generated half of the + * bundles (commit 09b4f4e4e): a leaf whose digest no longer matches its source is stale and serves the source text instead. + * + * An entry exists only while the leaf IS such a copy. Re-translate the leaf in + * `.objects.generated.ts` and the next extract drops its entry by + * itself — the table makes no claim about text a translator wrote. A path with + * no entry is LEGACY-TRUSTED and never reported stale. + * + * ⚠️ Do not "fix" a staleness report by editing this file. Refreshing a digest + * records that the current text was copied from the current source, which is + * the false claim the mechanism exists to detect. Fix the TRANSLATION. + */ + +export const koGeneratedSourceHashes: Readonly> = { + "objects.sys_file.fields.etag.label": "a62e7fe0bac46fcb", +}; diff --git a/packages/services/service-storage/src/translations/pt-BR.objects.generated.ts b/packages/services/service-storage/src/translations/pt-BR.objects.generated.ts new file mode 100644 index 00000000000..8ea8f57c22c --- /dev/null +++ b/packages/services/service-storage/src/translations/pt-BR.objects.generated.ts @@ -0,0 +1,182 @@ +// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license. + +/** + * Auto-generated by 'os i18n extract' for locale 'pt-BR'. + * Edit translations in place; re-run extract (with --merge) to fill new gaps. + * Do not hand-edit the structure — only the leaf string values. + * Merge only fills gaps: correcting a source label/description does not + * push the correction into a leaf here that already holds a translation — + * a present-but-stale string is not a gap, so it is left as-is. Re-translate + * it by hand when its source changes; nothing here or in `os i18n check` + * tells a leaf a translator updated on purpose from one nobody has looked + * at since the source moved. + */ + +import type { TranslationData } from '@objectstack/spec/system'; + +export const ptBRObjects: NonNullable = { + sys_file: { + label: "Arquivo do sistema", + pluralLabel: "Arquivos do sistema", + description: "Metadados de arquivos do serviço de armazenamento (mapeamento fileId ↔ key)", + fields: { + id: { + label: "ID do arquivo" + }, + key: { + label: "Chave de armazenamento" + }, + name: { + label: "Nome do arquivo" + }, + mime_type: { + label: "Tipo MIME" + }, + size: { + label: "Tamanho (bytes)" + }, + scope: { + label: "Escopo", + options: { + user: "Usuário", + tenant: "Locatário", + private: "Privado", + temp: "Temporário", + attachments: "Anexos" + } + }, + bucket: { + label: "Bucket" + }, + acl: { + label: "Controle de acesso", + options: { + private: "Privado", + public_read: "Leitura pública" + } + }, + status: { + label: "Status", + options: { + pending: "Upload pendente", + committed: "Confirmado", + deleted: "Excluído" + } + }, + etag: { + label: "ETag" + }, + owner_id: { + label: "ID do proprietário", + help: "Usuário que enviou o arquivo (autoria, não o dono da referência de campo)" + }, + ref_object: { + label: "Objeto de referência", + help: "Nome curto do objeto do registro cujo campo possui este arquivo" + }, + ref_id: { + label: "Registro de referência", + help: "Chave primária do registro cujo campo possui este arquivo" + }, + ref_field: { + label: "Campo de referência", + help: "Nome do campo no registro proprietário que guarda o ID deste arquivo" + }, + released_ref_object: { + label: "Objeto de origem da liberação", + help: "Nome curto do objeto do registro que possuiu este arquivo por último, depois de liberá-lo" + }, + released_ref_id: { + label: "Registro de origem da liberação", + help: "Chave primária do registro que possuiu este arquivo por último, depois de liberá-lo" + }, + metadata: { + label: "Metadados (JSON)" + }, + created_at: { + label: "Criado em" + }, + updated_at: { + label: "Atualizado em" + }, + deleted_at: { + label: "Excluído em", + help: "Carimbo de tombstone — definido quando a última referência sys_attachment a um arquivo do escopo attachments é removida; o TTL do ciclo de vida recolhe a linha (e seus bytes armazenados, pela proteção de recolhimento do sys_file) após o período de carência. NULL para linhas ativas." + } + } + }, + sys_upload_session: { + label: "Sessão de upload do sistema", + pluralLabel: "Sessões de upload do sistema", + description: "Sessões de upload multipart retomáveis rastreadas pelo service-storage", + fields: { + id: { + label: "ID da sessão de upload" + }, + file_id: { + label: "ID do arquivo" + }, + key: { + label: "Chave de armazenamento" + }, + filename: { + label: "Nome do arquivo" + }, + mime_type: { + label: "Tipo MIME" + }, + total_size: { + label: "Tamanho total (bytes)" + }, + chunk_size: { + label: "Tamanho do bloco (bytes)" + }, + total_chunks: { + label: "Total de blocos" + }, + uploaded_chunks: { + label: "Blocos enviados" + }, + uploaded_size: { + label: "Tamanho enviado (bytes)" + }, + parts: { + label: "Partes enviadas (JSON)" + }, + resume_token: { + label: "Token de retomada" + }, + backend_upload_id: { + label: "ID de upload do backend" + }, + scope: { + label: "Escopo" + }, + bucket: { + label: "Bucket" + }, + metadata: { + label: "Metadados (JSON)" + }, + status: { + label: "Status", + options: { + in_progress: "Em andamento", + completing: "Concluindo", + completed: "Concluído", + failed: "Falhou", + expired: "Expirado" + } + }, + started_at: { + label: "Iniciado em" + }, + expires_at: { + label: "Expira em" + }, + updated_at: { + label: "Atualizado em" + } + } + } +}; diff --git a/packages/services/service-storage/src/translations/pt-BR.source-hashes.generated.ts b/packages/services/service-storage/src/translations/pt-BR.source-hashes.generated.ts new file mode 100644 index 00000000000..8e77b1a2f8c --- /dev/null +++ b/packages/services/service-storage/src/translations/pt-BR.source-hashes.generated.ts @@ -0,0 +1,26 @@ +// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. + +/** + * Auto-generated by 'os i18n extract' for locale 'pt-BR'. Do not hand-edit. + * + * Each entry is the digest of the SOURCE REVISION that this locale's leaf at + * that path is still a byte copy of — provenance for the generated half of the + * bundles (commit 09b4f4e4e): a leaf whose digest no longer matches its source is stale and serves the source text instead. + * + * An entry exists only while the leaf IS such a copy. Re-translate the leaf in + * `.objects.generated.ts` and the next extract drops its entry by + * itself — the table makes no claim about text a translator wrote. A path with + * no entry is LEGACY-TRUSTED and never reported stale. + * + * ⚠️ Do not "fix" a staleness report by editing this file. Refreshing a digest + * records that the current text was copied from the current source, which is + * the false claim the mechanism exists to detect. Fix the TRANSLATION. + */ + +export const ptBRGeneratedSourceHashes: Readonly> = { + "objects.sys_file.fields.bucket.label": "3aa22e888d1f90c0", + "objects.sys_file.fields.etag.label": "a62e7fe0bac46fcb", + "objects.sys_file.fields.status.label": "64a420165247654b", + "objects.sys_upload_session.fields.bucket.label": "3aa22e888d1f90c0", + "objects.sys_upload_session.fields.status.label": "64a420165247654b", +}; diff --git a/packages/services/service-storage/src/translations/ru.objects.generated.ts b/packages/services/service-storage/src/translations/ru.objects.generated.ts new file mode 100644 index 00000000000..f6d1735742d --- /dev/null +++ b/packages/services/service-storage/src/translations/ru.objects.generated.ts @@ -0,0 +1,182 @@ +// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license. + +/** + * Auto-generated by 'os i18n extract' for locale 'ru'. + * Edit translations in place; re-run extract (with --merge) to fill new gaps. + * Do not hand-edit the structure — only the leaf string values. + * Merge only fills gaps: correcting a source label/description does not + * push the correction into a leaf here that already holds a translation — + * a present-but-stale string is not a gap, so it is left as-is. Re-translate + * it by hand when its source changes; nothing here or in `os i18n check` + * tells a leaf a translator updated on purpose from one nobody has looked + * at since the source moved. + */ + +import type { TranslationData } from '@objectstack/spec/system'; + +export const ruObjects: NonNullable = { + sys_file: { + label: "Системный файл", + pluralLabel: "Системные файлы", + description: "Метаданные файлов службы хранения (соответствие fileId ↔ key)", + fields: { + id: { + label: "ID файла" + }, + key: { + label: "Ключ хранилища" + }, + name: { + label: "Имя файла" + }, + mime_type: { + label: "Тип MIME" + }, + size: { + label: "Размер (байт)" + }, + scope: { + label: "Область", + options: { + user: "Пользователь", + tenant: "Арендатор", + private: "Личный", + temp: "Временный", + attachments: "Вложения" + } + }, + bucket: { + label: "Бакет" + }, + acl: { + label: "Управление доступом", + options: { + private: "Личный", + public_read: "Публичное чтение" + } + }, + status: { + label: "Статус", + options: { + pending: "Ожидает загрузки", + committed: "Зафиксирован", + deleted: "Удалён" + } + }, + etag: { + label: "ETag" + }, + owner_id: { + label: "ID владельца", + help: "Пользователь, загрузивший файл (авторство, а не владелец ссылки из поля)" + }, + ref_object: { + label: "Ссылающийся объект", + help: "Краткое имя объекта записи, поле которой владеет этим файлом" + }, + ref_id: { + label: "Ссылающаяся запись", + help: "Первичный ключ записи, поле которой владеет этим файлом" + }, + ref_field: { + label: "Ссылающееся поле", + help: "Имя поля записи-владельца, в котором хранится ID этого файла" + }, + released_ref_object: { + label: "Объект, освободивший файл", + help: "Краткое имя объекта записи, которая последней владела файлом, после того как она его освободила" + }, + released_ref_id: { + label: "Запись, освободившая файл", + help: "Первичный ключ записи, которая последней владела файлом, после того как она его освободила" + }, + metadata: { + label: "Метаданные (JSON)" + }, + created_at: { + label: "Создано" + }, + updated_at: { + label: "Обновлено" + }, + deleted_at: { + label: "Удалено", + help: "Метка надгробия — устанавливается, когда удаляется последняя ссылка sys_attachment на файл области attachments; по истечении льготного периода TTL жизненного цикла удаляет строку (и её байты в хранилище — через защиту удаления sys_file). Для живых строк — NULL." + } + } + }, + sys_upload_session: { + label: "Системный сеанс загрузки", + pluralLabel: "Системные сеансы загрузки", + description: "Возобновляемые сеансы составной загрузки, отслеживаемые service-storage", + fields: { + id: { + label: "ID сеанса загрузки" + }, + file_id: { + label: "ID файла" + }, + key: { + label: "Ключ хранилища" + }, + filename: { + label: "Имя файла" + }, + mime_type: { + label: "Тип MIME" + }, + total_size: { + label: "Общий размер (байт)" + }, + chunk_size: { + label: "Размер фрагмента (байт)" + }, + total_chunks: { + label: "Всего фрагментов" + }, + uploaded_chunks: { + label: "Загружено фрагментов" + }, + uploaded_size: { + label: "Загружено (байт)" + }, + parts: { + label: "Загруженные части (JSON)" + }, + resume_token: { + label: "Токен возобновления" + }, + backend_upload_id: { + label: "ID загрузки на бэкенде" + }, + scope: { + label: "Область" + }, + bucket: { + label: "Бакет" + }, + metadata: { + label: "Метаданные (JSON)" + }, + status: { + label: "Статус", + options: { + in_progress: "Выполняется", + completing: "Завершается", + completed: "Завершён", + failed: "Ошибка", + expired: "Истёк" + } + }, + started_at: { + label: "Начато" + }, + expires_at: { + label: "Истекает" + }, + updated_at: { + label: "Обновлено" + } + } + } +}; diff --git a/packages/services/service-storage/src/translations/ru.source-hashes.generated.ts b/packages/services/service-storage/src/translations/ru.source-hashes.generated.ts new file mode 100644 index 00000000000..27bc1b4f631 --- /dev/null +++ b/packages/services/service-storage/src/translations/ru.source-hashes.generated.ts @@ -0,0 +1,22 @@ +// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. + +/** + * Auto-generated by 'os i18n extract' for locale 'ru'. Do not hand-edit. + * + * Each entry is the digest of the SOURCE REVISION that this locale's leaf at + * that path is still a byte copy of — provenance for the generated half of the + * bundles (commit 09b4f4e4e): a leaf whose digest no longer matches its source is stale and serves the source text instead. + * + * An entry exists only while the leaf IS such a copy. Re-translate the leaf in + * `.objects.generated.ts` and the next extract drops its entry by + * itself — the table makes no claim about text a translator wrote. A path with + * no entry is LEGACY-TRUSTED and never reported stale. + * + * ⚠️ Do not "fix" a staleness report by editing this file. Refreshing a digest + * records that the current text was copied from the current source, which is + * the false claim the mechanism exists to detect. Fix the TRANSLATION. + */ + +export const ruGeneratedSourceHashes: Readonly> = { + "objects.sys_file.fields.etag.label": "a62e7fe0bac46fcb", +}; diff --git a/packages/services/service-storage/src/translations/zh-Hant.objects.generated.ts b/packages/services/service-storage/src/translations/zh-Hant.objects.generated.ts new file mode 100644 index 00000000000..87918e4f4bd --- /dev/null +++ b/packages/services/service-storage/src/translations/zh-Hant.objects.generated.ts @@ -0,0 +1,182 @@ +// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license. + +/** + * Auto-generated by 'os i18n extract' for locale 'zh-Hant'. + * Edit translations in place; re-run extract (with --merge) to fill new gaps. + * Do not hand-edit the structure — only the leaf string values. + * Merge only fills gaps: correcting a source label/description does not + * push the correction into a leaf here that already holds a translation — + * a present-but-stale string is not a gap, so it is left as-is. Re-translate + * it by hand when its source changes; nothing here or in `os i18n check` + * tells a leaf a translator updated on purpose from one nobody has looked + * at since the source moved. + */ + +import type { TranslationData } from '@objectstack/spec/system'; + +export const zhHantObjects: NonNullable = { + sys_file: { + label: "系統檔案", + pluralLabel: "系統檔案", + description: "儲存服務的檔案中繼資料(fileId ↔ key 對應)", + fields: { + id: { + label: "檔案 ID" + }, + key: { + label: "儲存鍵" + }, + name: { + label: "檔案名稱" + }, + mime_type: { + label: "MIME 類型" + }, + size: { + label: "大小(位元組)" + }, + scope: { + label: "作用範圍", + options: { + user: "使用者", + tenant: "租用戶", + private: "私人", + temp: "暫存", + attachments: "附件" + } + }, + bucket: { + label: "儲存貯體" + }, + acl: { + label: "存取控制", + options: { + private: "私人", + public_read: "公開可讀" + } + }, + status: { + label: "狀態", + options: { + pending: "待上傳", + committed: "已提交", + deleted: "已刪除" + } + }, + etag: { + label: "ETag" + }, + owner_id: { + label: "擁有者 ID", + help: "上傳該檔案的使用者(表示作者身分,而非欄位參照的所屬方)" + }, + ref_object: { + label: "參照方物件", + help: "擁有此檔案之欄位所在記錄的物件短名稱" + }, + ref_id: { + label: "參照方記錄", + help: "擁有此檔案之欄位所在記錄的主鍵" + }, + ref_field: { + label: "參照方欄位", + help: "所屬記錄上保存此檔案 ID 的欄位名稱" + }, + released_ref_object: { + label: "釋放來源物件", + help: "最後擁有此檔案並已將其釋放之記錄所屬物件的短名稱" + }, + released_ref_id: { + label: "釋放來源記錄", + help: "最後擁有此檔案並已將其釋放之記錄的主鍵" + }, + metadata: { + label: "中繼資料(JSON)" + }, + created_at: { + label: "建立時間" + }, + updated_at: { + label: "更新時間" + }, + deleted_at: { + label: "刪除時間", + help: "墓碑時間戳記——當附件作用範圍檔案的最後一個 sys_attachment 參照被移除時設定;寬限期過後,生命週期 TTL 會回收該列(並經 sys_file 回收防護回收其儲存位元組)。存活列為 NULL。" + } + } + }, + sys_upload_session: { + label: "系統上傳工作階段", + pluralLabel: "系統上傳工作階段", + description: "由 service-storage 追蹤的可續傳分段上傳工作階段", + fields: { + id: { + label: "上傳工作階段 ID" + }, + file_id: { + label: "檔案 ID" + }, + key: { + label: "儲存鍵" + }, + filename: { + label: "檔案名稱" + }, + mime_type: { + label: "MIME 類型" + }, + total_size: { + label: "總大小(位元組)" + }, + chunk_size: { + label: "分段大小(位元組)" + }, + total_chunks: { + label: "分段總數" + }, + uploaded_chunks: { + label: "已上傳分段數" + }, + uploaded_size: { + label: "已上傳大小(位元組)" + }, + parts: { + label: "已上傳分段(JSON)" + }, + resume_token: { + label: "續傳權杖" + }, + backend_upload_id: { + label: "後端上傳 ID" + }, + scope: { + label: "作用範圍" + }, + bucket: { + label: "儲存貯體" + }, + metadata: { + label: "中繼資料(JSON)" + }, + status: { + label: "狀態", + options: { + in_progress: "上傳中", + completing: "合併中", + completed: "已完成", + failed: "失敗", + expired: "已過期" + } + }, + started_at: { + label: "開始時間" + }, + expires_at: { + label: "到期時間" + }, + updated_at: { + label: "更新時間" + } + } + } +}; diff --git a/packages/services/service-storage/src/translations/zh-Hant.source-hashes.generated.ts b/packages/services/service-storage/src/translations/zh-Hant.source-hashes.generated.ts new file mode 100644 index 00000000000..13b2873bd1e --- /dev/null +++ b/packages/services/service-storage/src/translations/zh-Hant.source-hashes.generated.ts @@ -0,0 +1,22 @@ +// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. + +/** + * Auto-generated by 'os i18n extract' for locale 'zh-Hant'. Do not hand-edit. + * + * Each entry is the digest of the SOURCE REVISION that this locale's leaf at + * that path is still a byte copy of — provenance for the generated half of the + * bundles (commit 09b4f4e4e): a leaf whose digest no longer matches its source is stale and serves the source text instead. + * + * An entry exists only while the leaf IS such a copy. Re-translate the leaf in + * `.objects.generated.ts` and the next extract drops its entry by + * itself — the table makes no claim about text a translator wrote. A path with + * no entry is LEGACY-TRUSTED and never reported stale. + * + * ⚠️ Do not "fix" a staleness report by editing this file. Refreshing a digest + * records that the current text was copied from the current source, which is + * the false claim the mechanism exists to detect. Fix the TRANSLATION. + */ + +export const zhHantGeneratedSourceHashes: Readonly> = { + "objects.sys_file.fields.etag.label": "a62e7fe0bac46fcb", +};