@cosmicdrift/kumiko-locale-es 0.378.0 → 0.379.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-locale-es",
3
- "version": "0.378.0",
3
+ "version": "0.379.0",
4
4
  "description": "Spanish UI and mail copy for Kumiko framework screens. Opt in by mounting localeEs() + localeEsClient().",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -28,7 +28,7 @@
28
28
  }
29
29
  },
30
30
  "dependencies": {
31
- "@cosmicdrift/kumiko-framework": "0.378.0"
31
+ "@cosmicdrift/kumiko-framework": "0.379.0"
32
32
  },
33
33
  "publishConfig": {
34
34
  "registry": "https://registry.npmjs.org",
package/src/strings.ts CHANGED
@@ -46,15 +46,19 @@ export const localeEsBundle: Readonly<Record<string, string>> = {
46
46
  "audit.log.col.actor": "Actor",
47
47
  "audit.log.col.aggregateId": "ID de agregado",
48
48
  "audit.log.col.aggregateType": "Tipo de agregado",
49
+ "audit.log.col.tenant": "Inquilino",
49
50
  "audit.log.col.type": "Evento",
50
51
  "audit.log.col.when": "Fecha",
51
52
  "audit.log.detail.field.id": "ID del evento",
52
53
  "audit.log.detail.metadata": "Metadatos",
53
54
  "audit.log.detail.payload": "Payload del evento",
54
- "audit.log.detail.subtitle":
55
- "Vista de detalle de solo lectura de un evento del registro de auditoría, con actor, marca de tiempo, agregado y el payload y los metadatos del evento en bruto; se accede desde una fila del registro de auditoría.",
55
+ "audit.log.description": "Todos los eventos de este inquilino. Una fila abre los detalles.",
56
+ "audit.log.allTenants.description":
57
+ "Todos los eventos de todos los inquilinos. Una fila abre los detalles.",
58
+ "audit.log.detail.subtitle": "Un evento con su actor, fecha y datos almacenados.",
56
59
  "audit.log.details": "Detalles",
57
60
  "audit:nav.auditLog": "Registro de auditoría",
61
+ "audit:nav.auditLogAllTenants": "Registro de auditoría (todos los inquilinos)",
58
62
  "auth-mfa:entity:__action-form__:field:code": "Código de tu app de autenticación",
59
63
  "auth.errors.accountLocked": "Cuenta bloqueada temporalmente.",
60
64
  "auth.errors.accountLockedRetry": "Cuenta bloqueada. Vuelve a intentarlo en {minutes} minutos.",
@@ -528,10 +532,18 @@ export const localeEsBundle: Readonly<Record<string, string>> = {
528
532
  "errors.unconfigured": "Esta función todavía no está configurada.",
529
533
  "errors.uniqueViolation": "Esta entrada ya existe.",
530
534
  "errors.unprocessable": "No se pudo procesar la solicitud.",
535
+ "errors.file.violatesBindTarget": "Este archivo no cumple los requisitos del campo de destino.",
531
536
  "errors.validation.custom": "Valor no válido.",
532
537
  "errors.validation.failed": "Validación fallida.",
533
538
  "errors.validation.invalid_element": "Entrada no válida.",
534
539
  "errors.validation.invalid_format": "Formato no válido.",
540
+ "errors.validation.invalid_format.email":
541
+ "Correo electrónico no válido, p. ej. nombre@ejemplo.es.",
542
+ "errors.validation.invalid_format.url": "Dirección web no válida, p. ej. https://ejemplo.es.",
543
+ "errors.validation.invalid_format.date": "Fecha no válida, p. ej. 20/10/2026.",
544
+ "errors.validation.invalid_format.datetime": "Fecha y hora no válidas, p. ej. 20/10/2026 14:30.",
545
+ "errors.validation.invalid_format.uuid":
546
+ "ID no válido, p. ej. 123e4567-e89b-12d3-a456-426614174000.",
535
547
  "errors.validation.invalid_key": "Clave no válida.",
536
548
  "errors.validation.invalid_option": "Selección no válida.",
537
549
  "errors.validation.invalid_type": "Valor no válido.",
@@ -548,6 +560,8 @@ export const localeEsBundle: Readonly<Record<string, string>> = {
548
560
  "kumiko.validation.number.min": "Debe ser al menos {minimum}.",
549
561
  "kumiko.validation.number.max": "Debe ser como máximo {maximum}.",
550
562
  "errors.validation.too_small": "Demasiado pequeño o demasiado corto (mínimo: {minimum}).",
563
+ "errors.validation.list_min_rows.one": "Se requiere al menos 1 fila.",
564
+ "errors.validation.list_min_rows.other": "Se requieren al menos {minimum} filas.",
551
565
  "errors.validation.unexpected_field": "Campo desconocido.",
552
566
  "errors.validation.unrecognized_keys": "Campos desconocidos.",
553
567
  "errors.versionConflict": "El registro se modificó mientras tanto. Recarga e inténtalo de nuevo.",
@@ -743,18 +757,24 @@ export const localeEsBundle: Readonly<Record<string, string>> = {
743
757
  "kumiko.field.embedded-list.empty-cta": "Añadir la primera fila",
744
758
  "kumiko.field.embedded-list.move-down": "Mover abajo",
745
759
  "kumiko.field.embedded-list.move-up": "Mover arriba",
746
- "kumiko.field.embedded-list.paste-cells-unmatched":
747
- "{count} celda(s) no tenían una opción coincidente y no se modificaron.",
748
- "kumiko.field.embedded-list.paste-rows-truncated":
749
- "Se descartaron {count} fila(s) pegadas (se alcanzó el número máximo de filas).",
760
+ "kumiko.field.embedded-list.paste-cells-unmatched.one":
761
+ "1 celda no tenía una opción coincidente y no se modificó.",
762
+ "kumiko.field.embedded-list.paste-cells-unmatched.other":
763
+ "{count} celdas no tenían una opción coincidente y no se modificaron.",
764
+ "kumiko.field.embedded-list.paste-rows-truncated.one":
765
+ "Se descartó 1 fila pegada (se alcanzó el número máximo de filas).",
766
+ "kumiko.field.embedded-list.paste-rows-truncated.other":
767
+ "Se descartaron {count} filas pegadas (se alcanzó el número máximo de filas).",
750
768
  "kumiko.field.embedded-list.remove-row": "Quitar fila",
751
769
  "kumiko.field.file-list.add": "Añadir archivo",
752
770
  "kumiko.field.file-list.empty": "Aún no hay archivos.",
771
+ "kumiko.field.dropzone.limit-count": "hasta {count} archivos",
772
+ "kumiko.field.dropzone.limit-size": "hasta {size} por archivo",
773
+ "kumiko.field.dropzone.title": "Arrastra archivos aquí o haz clic para elegir",
753
774
  "kumiko.field.file-list.move-down": "Mover archivo hacia abajo",
754
775
  "kumiko.field.file-list.move-up": "Mover archivo hacia arriba",
755
776
  "kumiko.field.file-upload.attached": "Archivo adjunto",
756
777
  "kumiko.field.file-upload.change": "Cambiar",
757
- "kumiko.field.file-upload.failed": "Error al subir",
758
778
  "kumiko.field.file-upload.remove": "Quitar",
759
779
  "kumiko.field.file-upload.upload": "Subir",
760
780
  "kumiko.field.fillAction.failed": "No se pudo obtener una sugerencia.",
@@ -803,6 +823,9 @@ export const localeEsBundle: Readonly<Record<string, string>> = {
803
823
  "kumiko.list.count.one": "1 entrada",
804
824
  "kumiko.list.count.other": "{count} entradas",
805
825
  "kumiko.list.empty.filtered": "Ninguna entrada coincide con la búsqueda o los filtros.",
826
+ "kumiko.list.empty.defaultFiltered":
827
+ "Ninguna entrada coincide con el filtro predeterminado. Muestra todo para incluir las entradas fuera de él.",
828
+ "kumiko.list.empty.showAll": "Mostrar todo",
806
829
  "kumiko.list.empty.hint": "Crea la primera para empezar.",
807
830
  "kumiko.list.empty.title": "Todavía no hay entradas.",
808
831
  "kumiko.list.end-of-list": "— Fin de la lista —",
@@ -842,6 +865,7 @@ export const localeEsBundle: Readonly<Record<string, string>> = {
842
865
  "kumiko.planCard.priceUnavailable": "Precio no disponible",
843
866
  "kumiko.reference.system-tenant": "Sistema",
844
867
  "kumiko.reference.system-user": "Sistema",
868
+ "kumiko.reference.unknown-user": "Desconocido",
845
869
  "kumiko.rowAction.failed": "La acción falló",
846
870
  "kumiko.clientAction.success": "Hecho.",
847
871
  "kumiko.clientAction.unregistered": "Esta acción no está disponible en esta aplicación.",
@@ -878,6 +902,10 @@ export const localeEsBundle: Readonly<Record<string, string>> = {
878
902
  "kumiko.widget.upload.done": "Subido",
879
903
  "kumiko.widget.upload.error": "Fallido",
880
904
  "kumiko.widget.upload.rejected-type": "Tipo de archivo no permitido",
905
+ "kumiko.widget.upload.invalid-type": "Tipo o contenido de archivo no permitido",
906
+ "kumiko.widget.upload.max-count": "Como máximo {count} archivos",
907
+ "kumiko.widget.upload.remove": "Quitar archivo",
908
+ "kumiko.widget.upload.too-large": "El archivo es demasiado grande",
881
909
  "kumiko.widget.upload.uploading": "Subiendo…",
882
910
  "kumiko.wizard.next-with-title": "Siguiente: {title}",
883
911
  "kumiko.wizard.save-and-close": "Guardar y cerrar",
@@ -1002,6 +1030,8 @@ export const localeEsBundle: Readonly<Record<string, string>> = {
1002
1030
  "secrets.errors.invalidValue": "Este valor no es válido para este secreto.",
1003
1031
  "screen:api-token-create.title": "Crear un token nuevo",
1004
1032
  "screen:api-tokens.title": "Tokens de acceso personal",
1033
+ "screen:audit-log-all-tenants-detail.title": "Evento",
1034
+ "screen:audit-log-all-tenants.title": "Registro de auditoría (todos los inquilinos)",
1005
1035
  "screen:audit-log-detail.title": "Evento",
1006
1036
  "screen:audit-log.title": "Registro de auditoría",
1007
1037
  "screen:auth-mfa-disable.title": "Desactivar la verificación en dos pasos",
@@ -1086,7 +1116,9 @@ export const localeEsBundle: Readonly<Record<string, string>> = {
1086
1116
  "tags.manage.cancel": "Cancelar",
1087
1117
  "tags.manage.create": "Crear etiqueta",
1088
1118
  "tags.manage.delete": "Eliminar",
1089
- "tags.manage.deleteConfirmDesc": "Se quitará de {count} objetos. Esto no se puede deshacer.",
1119
+ "tags.manage.deleteConfirmDesc.one": "Se quitará de 1 objeto. Esto no se puede deshacer.",
1120
+ "tags.manage.deleteConfirmDesc.other":
1121
+ "Se quitará de {count} objetos. Esto no se puede deshacer.",
1090
1122
  "tags.manage.deleteConfirmTitle": "¿Eliminar la etiqueta «{name}»?",
1091
1123
  "tags.manage.edit": "Editar",
1092
1124
  "tags.manage.namePlaceholder": "Nombre de la etiqueta",
@@ -1107,6 +1139,25 @@ export const localeEsBundle: Readonly<Record<string, string>> = {
1107
1139
  "tags:entity:tag:field:color": "Color",
1108
1140
  "tags:entity:tag:field:name": "Nombre",
1109
1141
  "tags:entity:tag:field:scope": "Ámbito",
1142
+ "template-resolver:write:upsert-system:title": "Guardar plantilla del sistema",
1143
+ "template-resolver:write:upsert-tenant:title": "Guardar plantilla",
1144
+ "template-resolver:write:publish:title": "Publicar plantilla",
1145
+ "template-resolver:write:archive:title": "Archivar plantilla",
1146
+ "template-resolver:write:publish-system:title": "Publicar plantilla del sistema",
1147
+ "template-resolver:write:archive-system:title": "Archivar plantilla del sistema",
1148
+ "template-resolver:write:discard-draft:title": "Descartar borrador",
1149
+ "template-resolver:write:discard-draft-system:title":
1150
+ "Descartar borrador de la plantilla del sistema",
1151
+ "template-resolver:write:reset-to-system:title": "Restablecer la plantilla del sistema",
1152
+ "template-resolver:write:set:title": "Guardar texto",
1153
+ "template-resolver:write:import-bundle:title": "Importar plantilla",
1154
+ "template-resolver:write:import-bundle-system:title": "Importar plantilla del sistema",
1155
+ "template-resolver:write:copy-locale:title": "Copiar plantilla a otro idioma",
1156
+ "template-resolver:write:resource-upload:title": "Subir imagen o adjunto",
1157
+ "template-resolver:write:resource-remove:title": "Quitar imagen o adjunto",
1158
+ "template-resolver:write:resource-link-pdf:title": "Adjuntar plantilla PDF",
1159
+ "template-resolver:write:send-test:title": "Enviar correo de prueba",
1160
+ "template-resolver:write:patch-draft:title": "Editar borrador de la plantilla",
1110
1161
  "template-resolver.documentEditor.button": "Botón",
1111
1162
  "template-resolver.documentEditor.buttonDefaultText": "Confirmar",
1112
1163
  "template-resolver.documentEditor.buttonTarget": "Destino del botón",
@@ -1204,6 +1255,8 @@ export const localeEsBundle: Readonly<Record<string, string>> = {
1204
1255
  "Solo la plataforma mantiene esta plantilla; no se puede sobrescribir por cliente.",
1205
1256
  "templateResolver.errors.templateNotTenantEditable":
1206
1257
  "Solo la plataforma puede editar esta plantilla.",
1258
+ "templateResolver.overview.lockedOverride":
1259
+ "Versión propia guardada, pero no se entrega: la plantilla no está habilitada para los clientes.",
1207
1260
  "templateResolver.errors.template.targetExists":
1208
1261
  "Ya existe una plantilla para el idioma «{detail}»; sobrescríbela de forma explícita para reemplazarla.",
1209
1262
  "templateResolver.warnings.resourceNotUploaded": "Imagen no subida: {detail}",
@@ -1508,6 +1561,11 @@ export const localeEsBundle: Readonly<Record<string, string>> = {
1508
1561
  "Edita el diseño del correo o el papel de carta del PDF.",
1509
1562
  "documentDesigner.search": "Buscar plantillas",
1510
1563
  "documentDesigner.action.edit": "Editar",
1564
+ "documentDesigner.status.lockedOverride": "No entregada",
1565
+ "documentDesigner.action.resetLockedOverride": "Quitar versión propia",
1566
+ "documentDesigner.action.resetLockedOverride.confirm":
1567
+ "Se archiva la versión propia guardada de un idioma (primero alemán) y sigue en uso la versión de la plataforma. Si la plantilla tiene más idiomas, hay que repetirlo para cada uno.",
1568
+ "documentDesigner.action.resetLockedOverride.confirmLabel": "Quitar",
1511
1569
  "documentDesigner.col.template": "Plantilla",
1512
1570
  "documentDesigner.col.kind": "Tipo",
1513
1571
  "documentDesigner.col.origin": "Origen",
@@ -1535,7 +1593,8 @@ export const localeEsBundle: Readonly<Record<string, string>> = {
1535
1593
  "documentDesigner.status.draftVersion": "Borrador v{version}",
1536
1594
  "documentDesigner.usedBy.allMails": "todos los correos",
1537
1595
  "documentDesigner.usedBy.allPdfs": "todos los PDF",
1538
- "documentDesigner.usedBy.templates": "{count} plantillas",
1596
+ "documentDesigner.usedBy.templates.one": "1 plantilla",
1597
+ "documentDesigner.usedBy.templates.other": "{count} plantillas",
1539
1598
  "documentDesigner.usedBy.title": "Usada por",
1540
1599
  "documentDesigner.usedBy.none": "Ninguna plantilla usa todavía este diseño.",
1541
1600
  "documentDesigner.overriddenBy.tenants": "{active} organizaciones",
@@ -1600,9 +1659,13 @@ export const localeEsBundle: Readonly<Record<string, string>> = {
1600
1659
  "documentDesigner.editor.origin.none": "Todavía no hay ningún diseño.",
1601
1660
  "documentDesigner.editor.origin.system":
1602
1661
  "Ves el diseño del sistema. Al guardar se crea una personalización para tu organización.",
1603
- "documentDesigner.editor.origin.tenant.mails":
1662
+ "documentDesigner.editor.origin.tenant.mails.one":
1663
+ "Sustituye el diseño del sistema v{version}. Se aplica a 1 plantilla de correo de esta organización.",
1664
+ "documentDesigner.editor.origin.tenant.mails.other":
1604
1665
  "Sustituye el diseño del sistema v{version}. Se aplica a {count} plantillas de correo de esta organización.",
1605
- "documentDesigner.editor.origin.tenant.pdfs":
1666
+ "documentDesigner.editor.origin.tenant.pdfs.one":
1667
+ "Sustituye el papel de carta del sistema v{version}. Se aplica a 1 plantilla PDF de esta organización.",
1668
+ "documentDesigner.editor.origin.tenant.pdfs.other":
1606
1669
  "Sustituye el papel de carta del sistema v{version}. Se aplica a {count} plantillas PDF de esta organización.",
1607
1670
  "documentDesigner.editor.origin.platformPlain": "Diseño del sistema v{version}",
1608
1671
  "documentDesigner.editor.origin.platformCount":
@@ -1626,9 +1689,13 @@ export const localeEsBundle: Readonly<Record<string, string>> = {
1626
1689
  "Aquí se inserta el contenido de cada plantilla de correo. El asunto y el texto de vista previa provienen de la plantilla.",
1627
1690
  "documentDesigner.editor.slot.pdf": "Aquí se inserta el contenido de cada plantilla PDF.",
1628
1691
  "documentDesigner.editor.footer.checking": "Comprobando el diseño …",
1629
- "documentDesigner.editor.footer.okMail":
1692
+ "documentDesigner.editor.footer.okMail.one":
1693
+ "Marcador de contenido presente. Tras publicar, el cambio se aplica a 1 plantilla.",
1694
+ "documentDesigner.editor.footer.okMail.other":
1630
1695
  "Marcador de contenido presente. Tras publicar, el cambio se aplica a {count} plantillas.",
1631
- "documentDesigner.editor.footer.okPdf":
1696
+ "documentDesigner.editor.footer.okPdf.one":
1697
+ "Marcador de contenido presente. Tras publicar, el cambio se aplica a 1 plantilla.",
1698
+ "documentDesigner.editor.footer.okPdf.other":
1632
1699
  "Marcador de contenido presente. Tras publicar, el cambio se aplica a {count} plantillas.",
1633
1700
  "documentDesigner.editor.discard": "Descartar cambios",
1634
1701
  "documentDesigner.editor.save": "Guardar",
@@ -1735,7 +1802,7 @@ export const localeEsBundle: Readonly<Record<string, string>> = {
1735
1802
  "Los correos transaccionales no necesitan enlace de baja. Con «Marketing» el diseño debe incluirlo.",
1736
1803
  "documentDesigner.mail.chrome.title": "Cabecera y pie",
1737
1804
  "documentDesigner.mail.chrome.headerChip": "Etiqueta en la cabecera",
1738
- "documentDesigner.mail.chrome.headerChipPlaceholder": "p. ej. Nueva incidencia",
1805
+ "documentDesigner.mail.chrome.headerChipPlaceholder": "p. ej. Recordatorio",
1739
1806
  "documentDesigner.mail.chrome.tone": "Tono",
1740
1807
  "documentDesigner.mail.chrome.toneAccent": "Color de acento (predeterminado)",
1741
1808
  "documentDesigner.mail.chrome.toneInfo": "Info (gris azulado)",
@@ -1804,7 +1871,8 @@ export const localeEsBundle: Readonly<Record<string, string>> = {
1804
1871
  "documentDesigner.mail.preview.samplesHint":
1805
1872
  "Los importes y las fechas se formatean según los ajustes de la organización.",
1806
1873
  "documentDesigner.mail.preview.missingInContent": "falta en el contenido",
1807
- "documentDesigner.mail.preview.entries": "{count} entradas",
1874
+ "documentDesigner.mail.preview.entries.one": "1 entrada",
1875
+ "documentDesigner.mail.preview.entries.other": "{count} entradas",
1808
1876
  "documentDesigner.mail.preview.checks": "Comprobación",
1809
1877
  "documentDesigner.mail.preview.checksHint":
1810
1878
  "Lo que encontró el servidor al renderizar este correo.",
@@ -1,37 +0,0 @@
1
- import { describe, expect, test } from "bun:test";
2
- import { localeEsBundle } from "../strings";
3
- import { frameworkEnCatalog } from "./en-catalog";
4
-
5
- function placeholders(s: string): string[] {
6
- return [...s.matchAll(/\{(\w+)\}/g)].map((m) => m[1] ?? "").sort();
7
- }
8
-
9
- describe("locale-es completeness", () => {
10
- test("has every English framework key", () => {
11
- const missing = Object.keys(frameworkEnCatalog).filter((k) => localeEsBundle[k] === undefined);
12
- expect(missing).toEqual([]);
13
- });
14
-
15
- test("has no stale extra keys", () => {
16
- const extra = Object.keys(localeEsBundle).filter((k) => frameworkEnCatalog[k] === undefined);
17
- expect(extra).toEqual([]);
18
- });
19
-
20
- test("interpolation placeholders match English", () => {
21
- for (const key of Object.keys(frameworkEnCatalog)) {
22
- expect(placeholders(localeEsBundle[key] ?? "")).toEqual(
23
- placeholders(frameworkEnCatalog[key] ?? ""),
24
- );
25
- }
26
- });
27
-
28
- test("uses localized tenant wording, not raw English tenant labels", () => {
29
- const roleAllowlist = new Set(["TenantAdmin", "SystemAdmin"]);
30
- const offenders: string[] = [];
31
- for (const [key, value] of Object.entries(localeEsBundle)) {
32
- if (roleAllowlist.has(value)) continue;
33
- if (/\btenants?\b/i.test(value)) offenders.push(key);
34
- }
35
- expect(offenders).toEqual([]);
36
- });
37
- });