This is an automated email from the ASF dual-hosted git repository.

tenthe pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/streampipes.git


The following commit(s) were added to refs/heads/dev by this push:
     new a88f417a0a ci(#4468): validate i18n catalogs in PRs (#4469)
a88f417a0a is described below

commit a88f417a0a8f03f2109dad368aeed6bc1bd389c2
Author: Philipp Zehnder <[email protected]>
AuthorDate: Mon May 18 12:20:24 2026 +0200

    ci(#4468): validate i18n catalogs in PRs (#4469)
---
 .github/workflows/pr-validation.yml |   5 +
 ui/deployment/i18n-validate.js      | 112 ++++++++++++
 ui/deployment/i18n/de.json          |  41 ++++-
 ui/deployment/i18n/en.json          |  37 ++++
 ui/deployment/i18n/pl.json          |  37 ++++
 ui/package-lock.json                | 354 +++++++++++++++++++++++++++---------
 ui/package.json                     |   8 +-
 7 files changed, 505 insertions(+), 89 deletions(-)

diff --git a/.github/workflows/pr-validation.yml 
b/.github/workflows/pr-validation.yml
index 5f869ab425..bd5182b029 100644
--- a/.github/workflows/pr-validation.yml
+++ b/.github/workflows/pr-validation.yml
@@ -62,6 +62,11 @@ jobs:
           DEVELOCITY_ACCESS_KEY: ${{ secrets.STREAMPIPES_DEVELOCITY_ACCESS_KEY 
}}
           NODE_OPTIONS: '-r @gradle-tech/develocity-agent/preload'
 
+      - name: Validate UI translations
+        working-directory: ./ui
+        run: |
+          npm run i18n:check
+
       - name: Format and Lint all files
         working-directory: ./ui
         run: |
diff --git a/ui/deployment/i18n-validate.js b/ui/deployment/i18n-validate.js
new file mode 100644
index 0000000000..3c9cbca156
--- /dev/null
+++ b/ui/deployment/i18n-validate.js
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+const fs = require('fs');
+const path = require('path');
+
+/*
+ * Validates the tracked ngx-translate source catalogs before the UI is built.
+ *
+ * The runtime files in src/assets/i18n are generated from deployment/i18n by
+ * prebuild.js, so this script intentionally validates deployment/i18n only.
+ */
+const I18N_DIRECTORIES = ['deployment/i18n'];
+const SOURCE_LANGUAGE = 'en';
+const TARGET_LANGUAGES = ['de', 'pl'];
+const PLACEHOLDER_PATTERN = /\{\{\s*[\w.]+\s*\}\}/g;
+
+let hasError = false;
+
+function readTranslations(directory, language) {
+    const filePath = path.join(directory, `${language}.json`);
+    try {
+        return JSON.parse(fs.readFileSync(filePath, 'utf8'));
+    } catch (error) {
+        reportError(`${filePath}: Could not read translation file.`);
+        return {};
+    }
+}
+
+function reportError(message) {
+    hasError = true;
+    console.error(`ERROR: ${message}`);
+}
+
+function getPlaceholders(value) {
+    // Treat {{name}} and {{ name }} as the same placeholder.
+    return new Set(
+        (String(value).match(PLACEHOLDER_PATTERN) || []).map(placeholder =>
+            placeholder.replace(/\s+/g, ''),
+        ),
+    );
+}
+
+function validateLanguage(directory, sourceTranslations, language) {
+    const translations = readTranslations(directory, language);
+    const sourceKeys = Object.keys(sourceTranslations);
+    const translationKeys = Object.keys(translations);
+    const sourceKeySet = new Set(sourceKeys);
+
+    for (const key of sourceKeys) {
+        // Every target catalog must contain all source keys.
+        if (!(key in translations)) {
+            reportError(`${directory}/${language}.json: Missing key 
"${key}".`);
+            continue;
+        }
+
+        // Empty values render as missing translations in the UI.
+        const value = translations[key];
+        if (value === null || value === '') {
+            reportError(
+                `${directory}/${language}.json: Missing translation for 
"${key}".`,
+            );
+            continue;
+        }
+
+        // Interpolation placeholders must survive translation unchanged.
+        const sourcePlaceholders = getPlaceholders(key);
+        const translationPlaceholders = getPlaceholders(value);
+        for (const placeholder of sourcePlaceholders) {
+            if (!translationPlaceholders.has(placeholder)) {
+                reportError(
+                    `${directory}/${language}.json: Translation for "${key}" 
is missing placeholder ${placeholder}.`,
+                );
+            }
+        }
+    }
+
+    // Extra keys indicate stale translations that extraction no longer finds.
+    for (const key of translationKeys) {
+        if (!sourceKeySet.has(key)) {
+            reportError(`${directory}/${language}.json: Extra key "${key}".`);
+        }
+    }
+}
+
+for (const directory of I18N_DIRECTORIES) {
+    const sourceTranslations = readTranslations(directory, SOURCE_LANGUAGE);
+    for (const language of TARGET_LANGUAGES) {
+        validateLanguage(directory, sourceTranslations, language);
+    }
+}
+
+if (hasError) {
+    process.exit(1);
+}
+
+console.log('All i18n translations are complete.');
diff --git a/ui/deployment/i18n/de.json b/ui/deployment/i18n/de.json
index 64f60da161..c638638018 100644
--- a/ui/deployment/i18n/de.json
+++ b/ui/deployment/i18n/de.json
@@ -29,6 +29,7 @@
   "A label for better readability": "Ein Bezeichner für bessere Lesbarkeit",
   "A longer description of this asset": "Eine längere Beschreibung dieses 
Assets",
   "A map visualization for spatial coordinates": "Eine Kartenvisualisierung 
für räumliche Koordinaten",
+  "A measurement field changed to a data type that conflicts with existing 
data. This needs manual adjustments. You can handle this error by following one 
of the given instructions:": "Ein Datentyp von einem Feld hat sich geändert, 
weshalb es einen Konflikt mit gespeicherten Daten gibt. Dies erfordert manuelle 
Anpassungen. Sie können diesen Fehler beheben, indem Sie eine der folgenden 
Anweisungen befolgen:",
   "A pie chart that shows the frequency of specific values": "Ein 
Kreisdiagramm, das die Häufigkeit bestimmter Werte anzeigt",
   "A short name of the asset": "Ein kurzer Name des Assets",
   "A simple chart that shows values on a value/time graph": "Ein einfaches 
Diagramm, das Werte in einem Wert/Zeit-Diagramm anzeigt",
@@ -95,6 +96,7 @@
   "Allow self - registration": "Selbst-Registrierung zulassen",
   "Allow self - service password recovery": "Wiederherstellung von Passwörtern 
im Self-Service erlauben",
   "Alternate IDs": "Alternative IDs",
+  "An unknown error has occurred": "Ein unbekannter Fehler ist aufgetreten",
   "Angle where the first slice starts (in degrees).": "Winkel, bei dem das 
erste Segment beginnt (in Grad).",
   "Angle where the gauge arc begins (in degrees).": "Winkel, bei dem der 
Tacho-Bogen beginnt (in Grad).",
   "Angle where the gauge arc ends (in degrees).": "Winkel, bei dem der 
Tacho-Bogen endet (in Grad).",
@@ -166,6 +168,7 @@
   "Certificates": "Zertifikate",
   "Change email": "E-Mail ändern",
   "Change password": "Passwort ändern",
+  "Change the identifier of the \"Data Lake\" by opening the pipeline element 
configuration to save the data in a new \"Data Lake\".": "Ändern Sie die 
Kennung des \"Data Lake\", indem Sie die Pipeline-Element-Konfiguration öffnen, 
um die Daten in einem neuen \"Data Lake\" zu speichern.",
   "Change the look and feel of your installation": "Darstellung der Anwendung 
ändern",
   "Changed": "Geändert",
   "Changing the current user's email will require a re-login.": "Änderung der 
E-Mail-Adresse erfordert eine erneute Anmeldung.",
@@ -185,6 +188,7 @@
   "Clear & use simple filters": "Löschen und einfache Filter verwenden",
   "Clear Assembly Area": "Pipeline-Bereich leeren",
   "Clear selection & reload": "Auswahl löschen & neu laden",
+  "Click to add label": "Klicken, um Label hinzuzufügen",
   "Click to load": "Klicken zum Laden",
   "Client Secret": "Client-Schlüssel",
   "Clockwise": "Im Uhrzeigersinn",
@@ -194,6 +198,7 @@
   "Clone options": "Optionen zum Klonen",
   "Close": "Schließen",
   "Code": "Code",
+  "Collapse preview": "Vorschau einklappen",
   "Color": "Farbe",
   "Color scheme": "Farbschema",
   "Color used above the high threshold.": "Farbe, die oberhalb des hohen 
Schwellenwerts verwendet wird.",
@@ -229,6 +234,7 @@
   "Create asset": "Asset erstellen",
   "Create asset links": "Asset-Links erstellen",
   "Create chart": "Diagramm erstellen",
+  "Create link": "Link erstellen",
   "Create new API key": "Neuen API-Schlüssel erstellen",
   "Create new account": "Neuen Account erstellen",
   "Create new dataset": "Neues Dataset erstellen",
@@ -302,8 +308,11 @@
   "Delete data": "Daten löschen",
   "Delete dataset": "Datensatz löschen",
   "Delete file": "Datei löschen",
+  "Delete historical data": "Historische Daten löschen",
+  "Delete label": "Label löschen",
   "Delete pipeline": "Pipeline löschen",
   "Delete service": "Service löschen",
+  "Delete site": "Standort löschen",
   "Delete user": "Benutzer löschen",
   "Deleting data...": "Daten löschen...",
   "Deleting pipeline...": "Löschen der Pipeline...",
@@ -386,9 +395,9 @@
   "Error in line {{rowNumber}}. Value for \"{{property}}\" is not set.": 
"Fehler in Zeile {{rowNumber}}. Wert für \"{{property}}\" ist nicht gesetzt.",
   "Error in line {{rowNumber}}. Value for \"{{property}}\" is not supported.": 
"Fehler in Zeile {{rowNumber}}. Wert für \"{{property}}\" wird nicht 
unterstützt.",
   "Error while uploading application package": "Fehler beim Hochladen des 
Anwendungspakets",
-  "Error: {{message}} with cause {{cause}}": "Fehler: {{message} mit Ursache 
{{cause}}",
+  "Error: {{message}} with cause {{cause}}": "Fehler: {{message}} mit Ursache 
{{cause}}",
   "Event Aggregation": "Aggregation",
-  "Event Transformation Configuration has changed": "",
+  "Event Transformation Configuration has changed": "Die Transformation von 
Events wurde geändert",
   "Everything older than": "Älter als",
   "Exact location of the site": "Genaue Lage des Standorts",
   "Excel template": "Excel Vorlage",
@@ -398,6 +407,7 @@
   "Exit fullscreen": "Vollbild verlassen",
   "Expand Less": "Ausklappen",
   "Expand More": "Einklappen",
+  "Expand preview": "Vorschau ausklappen",
   "Expires": "Läuft aus",
   "Export": "Exportieren",
   "Export Data": "Daten exportieren",
@@ -409,6 +419,7 @@
   "Export resources": "Ressourcen exportieren",
   "Exported items {{assetName}}": "Exportierte Items {{assetName}}",
   "Exporting resources...": "Ressourcen exportieren...",
+  "Fail": "Fehlgeschlagen",
   "False": "Falsch",
   "Field": "Feld",
   "Field Name": "Feldname",
@@ -512,6 +523,7 @@
   "Install the following pipeline elements and start the tutorial again:": 
"Installieren Sie die folgenden Pipeline-Elemente und starten Sie das 
Lernprogramm erneut:",
   "Installation": "Installation",
   "Installed": "Installiert",
+  "Installing": "Wird installiert",
   "Internally managed by {{appName}}": "Intern verwaltet von {{appName}}",
   "Interval [sec]": "Intervall [sec]",
   "Interval in seconds in which an event must arrive": "Sekundenintervall, in 
dem ein Ereignis eintreffen muss",
@@ -589,6 +601,7 @@
   "Manage Labels": "Labels verwalten",
   "Manage Sites": "Standorte verwalten",
   "Manage asset links": "Verwalten von Asset-Verknüpfungen",
+  "Manage datasets": "Datensätze verwalten",
   "Manage links": "Verwalten von Links",
   "Manage permissions": "Berechtigungen verwalten",
   "Manage permissions for adapter ": "Berechtigungen für Adapter verwalten",
@@ -671,10 +684,12 @@
   "No export providers found": "Keine Exportanbieter gefunden",
   "No fields selected.": "Keine Felder ausgewählt.",
   "No groups configured": "Keine Gruppen konfiguriert",
+  "No labels available - Click 'Manage Labels'": "Keine Labels verfügbar - 
Klicken Sie auf 'Labels verwalten'",
   "No linked resources": "Keine verknüpften Ressourcen",
   "No linked resources found.": "Keine verlinkten Ressourcen gefunden.",
   "No live preview available.": "Keine Live-Vorschau verfügbar.",
   "No location defined for this asset yet.": "Für dieses Asset ist noch kein 
Standort definiert.",
+  "No more information": "Keine weiteren Informationen",
   "No nodes selected yet": "Noch keine Knoten ausgewählt",
   "No numeric or boolean fields available.": "Keine numerischen oder 
booleschen Felder verfügbar.",
   "No table rows match the current filter.": "Keine Tabellenzeilen entsprechen 
dem aktuellen Filter.",
@@ -692,6 +707,8 @@
   "Oldest (ascending)": "Älteste zuerst (aufsteigend)",
   "Only admins and owners can manage permissions for this resource.": "Nur 
Administratoren und Eigentümer können die Berechtigungen für diese Ressource 
verwalten.",
   "Only linked resources are part of the application package.": "Nur 
verknüpfte Ressourcen sind Teil des Anwendungspakets.",
+  "Open Retention Log": "Aufbewahrungs Log öffnen",
+  "Open fullscreen": "Vollbild öffnen",
   "Optional override for decimal places. Leave empty to show original 
values.": "Optionale Überschreibung für Dezimalstellen. Leer lassen, um 
Originalwerte anzuzeigen.",
   "Options": "Optionen",
   "Order": "Sortieren",
@@ -794,6 +811,8 @@
   "Remove node": "Knoten entfernen",
   "Rename file": "Datei umbenennen",
   "Rename files": "Dateien umbenennen",
+  "Rename the changed fields": "Geänderte Felder umbenennen",
+  "Rename the fields with changed data types by using the \"Field Renamer\" 
data processor": "Benennen Sie die Felder mit geänderten Datentypen mit dem 
Datenprozessor \"Field Renamer\" um",
   "Repeat password": "Passwort wiederholen",
   "Require users to accept terms after login": "Benutzer müssen 
Nutzungsbedingungen nach Anmeldung akzeptieren",
   "Reset": "Zurücksetzen",
@@ -837,6 +856,7 @@
   "Save as template": "Als Vorlage speichern",
   "Save changes": "Änderungen speichern",
   "Save changes?": "Änderungen speichern?",
+  "Save in a new data lake": "In einem neuen Data Lake speichern",
   "Save pipeline": "Pipeline speichern",
   "Save template": "Vorlage speichern",
   "Saving metadata": "Speichern von Metadaten",
@@ -853,6 +873,7 @@
   "Secret Key": "Secret Key",
   "Select Adapter": "Adapter auswählen",
   "Select All": "Alle auswählen",
+  "Select CSV file": "CSV-Datei auswählen",
   "Select Data": "Daten auswählen",
   "Select Fields": "Felder auswählen",
   "Select Format": "Format auswählen",
@@ -931,6 +952,8 @@
   "Slide view": "Folienansicht",
   "Slider": "Slider",
   "Slides": "Folien",
+  "Sorry, there are no adapters that are currently idle": "Leider gibt es 
derzeit keine inaktiven Adapter",
+  "Sorry, there are no adapters that are currently running": "Leider gibt es 
derzeit keine laufenden Adapter",
   "Sorry, there are no pipelines that are currently idle.": "Leider gibt es 
keine Pipelines, die derzeit gestoppt sind.",
   "Sorry, there are no pipelines that are currently running.": "Es gibt leider 
keine Pipelines, die derzeit gestartet sind",
   "Sort": "Sortieren",
@@ -952,6 +975,7 @@
   "Start pipeline immediately": "Pipeline sofort starten",
   "Start selected adapters": "Ausgewählte Adapter starten",
   "Starting": "Starte",
+  "Starting adapter": "Adapter wird gestartet",
   "Starting adapter {{adapterName}}": "Adapter starten {{adapterName}}",
   "Starting pipeline": "Start der Pipeline",
   "Starting pipeline ": "Starte Pipeline",
@@ -964,6 +988,7 @@
   "Stop selected adapters": "Ausgewählte Adapter stoppen",
   "Stopped": "Gestoppt",
   "Stopping": "Stoppe",
+  "Stopping adapter": "Adapter wird gestoppt",
   "Stopping pipeline": "Pipeline stoppen",
   "Stopping pipeline...": "Pipeline stoppen...",
   "Store all events of this source in the internal data store": "Speichern 
aller Daten dieser Quelle im internen DataLake",
@@ -1038,6 +1063,8 @@
   "Title": "Titel",
   "Title must not be empty": "Titel darf nicht leer sein!",
   "To": "Bis",
+  "To delete a label, please remove the label from all assets": "Um ein Label 
zu löschen, entfernen Sie das Label bitte von allen Assets",
+  "To delete a site, please remove the site from all assets": "Um einen 
Standort zu löschen, entfernen Sie den Standort bitte von allen Assets",
   "To enable the map view, a map provider needs to be configured. Admins can 
configure map providers under Settings -> Sites.": "Um die Kartenansicht zu 
aktivieren, ist ein konfigurierter Kartenanbieter erforderlich. Administratoren 
können Kartenanbieter unter Einstellungen → Standorte verwalten.",
   "Tooltip": "Tooltip",
   "Tooltip Content": "Tooltip-Inhalt",
@@ -1052,7 +1079,9 @@
   "True": "Wahr",
   "Truncate Data": "Daten leeren",
   "Truncate data": "Daten leeren",
+  "Truncate the data of the dataset or delete it completely. All historical 
data is lost!": "Kürzen Sie die Daten des Datensatzes oder löschen Sie ihn 
vollständig. Alle historischen Daten gehen verloren!",
   "Truncating data...": "Daten leeren...",
+  "Trust": "Vertrauen",
   "Trying to send test mail...": "Test-Mail wird versendet...",
   "Type": "Typ",
   "Typography": "Typografie",
@@ -1060,6 +1089,7 @@
   "Unable to delete all associated pipelines because you are not the owner of 
the following pipelines: ": "Sie können nicht alle zugehörigen Pipelines 
löschen, da Sie nicht der Eigentümer der folgenden Pipelines sind:",
   "Uninstall": "Deinstallieren",
   "Uninstall selected": "Ausgewählte deinstallieren",
+  "Uninstalling": "Wird deinstalliert",
   "Unit": "Einheit",
   "Unit Transformation": "Einheitenumrechnung",
   "Unit conversion": "Einheitenumrechnung",
@@ -1072,6 +1102,7 @@
   "Update all changes to dashboard charts or discard current changes.": 
"Aktualisieren Sie alle Änderungen der Diagramme oder verwerfen Sie aktuelle 
Änderungen.",
   "Update asset links": "Asset-Links aktualisieren",
   "Update asset links or close.": "Asset-Links aktualisieren oder schließen.",
+  "Update link": "Link aktualisieren",
   "Update links": "Links aktualisieren",
   "Update pipeline": "Pipeline aktualisieren",
   "Update profile": "Profil aktualisieren",
@@ -1141,7 +1172,9 @@
   "Y": "Y",
   "Y Label": "Y-Label",
   "Yes": "Ja",
+  "You are about to start the following adapters:": "Sie sind dabei, die 
folgenden Adapter zu starten:",
   "You are about to start the following pipelines:": "Sie sind dabei, die 
folgenden Pipelines zu starten:",
+  "You are about to stop the following adapters:": "Sie sind dabei, die 
folgenden Adapter zu stoppen:",
   "You are about to stop the following pipelines:": "Sie sind dabei, die 
folgenden Pipelines zu stoppen:",
   "You are about to {{ action }} the following elements:": "Folgende Elemente 
{{ action }}:",
   "You can perform a forced stop, which will stop and reset the pipeline 
status.": "Sie können einen erzwungenen Stopp durchführen, der die Pipeline 
anhält und zurücksetzt.",
@@ -1155,9 +1188,11 @@
   "Your password successfully changed.": "Ihr Passwort wurde erfolgreich 
geändert.",
   "Your recent changes might have altered the data format. Reloading the 
sample ensures you are writing scripts for the most current data. Check your 
transformation rules after the refresh to ensure everything still aligns.": 
"Ihre letzten Änderungen haben möglicherweise das Datenformat verändert. Durch 
das Neuladen des Beispiels wird sichergestellt, dass Sie Skripte für die 
aktuellsten Daten schreiben. Prüfen Sie nach der Aktualisierung Ihre 
Transformationsregeln, um sicherzustellen, da [...]
   "assets are hidden because no valid location is configured.": "Assets sind 
ausgeblendet, weil kein gültiger Standort konfiguriert ist.",
+  "available": "verfügbar",
   "days": "Tage",
   "delete": "löschen",
   "error": "Fehler",
+  "install": "installieren",
   "left axis": "linke Achse",
   "marked as timestamp": "als Zeitstempel markiert",
   "new filename": "neuer Dateiname",
@@ -1167,6 +1202,7 @@
   "no log messages available": "keine Logs verfügbar",
   "no status information available": "keine Statusinformationen verfügbar",
   "no stored export providers": "keine gespeicherten Exportanbieter",
+  "not available": "nicht verfügbar",
   "of": "von",
   "or": "oder",
   "pipeline": "Pipeline",
@@ -1179,6 +1215,7 @@
   "showing first": "zeige zuerst",
   "success": "Erfolg",
   "to": "zu",
+  "uninstall": "deinstallieren",
   "visible to registered users": "sichtbar für registrierte Benutzer",
   "waiting": "Warten",
   "will be automatically migrated": "wird automatisch migriert",
diff --git a/ui/deployment/i18n/en.json b/ui/deployment/i18n/en.json
index eafd5f483a..81180aa564 100644
--- a/ui/deployment/i18n/en.json
+++ b/ui/deployment/i18n/en.json
@@ -29,6 +29,7 @@
   "A label for better readability": null,
   "A longer description of this asset": null,
   "A map visualization for spatial coordinates": null,
+  "A measurement field changed to a data type that conflicts with existing 
data. This needs manual adjustments. You can handle this error by following one 
of the given instructions:": null,
   "A pie chart that shows the frequency of specific values": null,
   "A short name of the asset": null,
   "A simple chart that shows values on a value/time graph": null,
@@ -95,6 +96,7 @@
   "Allow self - registration": null,
   "Allow self - service password recovery": null,
   "Alternate IDs": null,
+  "An unknown error has occurred": null,
   "Angle where the first slice starts (in degrees).": null,
   "Angle where the gauge arc begins (in degrees).": null,
   "Angle where the gauge arc ends (in degrees).": null,
@@ -166,6 +168,7 @@
   "Certificates": null,
   "Change email": null,
   "Change password": null,
+  "Change the identifier of the \"Data Lake\" by opening the pipeline element 
configuration to save the data in a new \"Data Lake\".": null,
   "Change the look and feel of your installation": null,
   "Changed": null,
   "Changing the current user's email will require a re-login.": null,
@@ -185,6 +188,7 @@
   "Clear & use simple filters": null,
   "Clear Assembly Area": null,
   "Clear selection & reload": null,
+  "Click to add label": null,
   "Click to load": null,
   "Client Secret": null,
   "Clockwise": null,
@@ -194,6 +198,7 @@
   "Clone options": null,
   "Close": null,
   "Code": null,
+  "Collapse preview": null,
   "Color": null,
   "Color scheme": null,
   "Color used above the high threshold.": null,
@@ -229,6 +234,7 @@
   "Create asset": null,
   "Create asset links": null,
   "Create chart": null,
+  "Create link": null,
   "Create new API key": null,
   "Create new account": null,
   "Create new dataset": null,
@@ -302,8 +308,11 @@
   "Delete data": null,
   "Delete dataset": null,
   "Delete file": null,
+  "Delete historical data": null,
+  "Delete label": null,
   "Delete pipeline": null,
   "Delete service": null,
+  "Delete site": null,
   "Delete user": null,
   "Deleting data...": null,
   "Deleting pipeline...": null,
@@ -398,6 +407,7 @@
   "Exit fullscreen": null,
   "Expand Less": null,
   "Expand More": null,
+  "Expand preview": null,
   "Expires": null,
   "Export": null,
   "Export Data": null,
@@ -409,6 +419,7 @@
   "Export resources": null,
   "Exported items {{assetName}}": "Exported items {{assetName}}",
   "Exporting resources...": null,
+  "Fail": null,
   "False": null,
   "Field": null,
   "Field Name": null,
@@ -512,6 +523,7 @@
   "Install the following pipeline elements and start the tutorial again:": 
null,
   "Installation": null,
   "Installed": null,
+  "Installing": null,
   "Internally managed by {{appName}}": "Internally managed by {{appName}}",
   "Interval [sec]": null,
   "Interval in seconds in which an event must arrive": null,
@@ -589,6 +601,7 @@
   "Manage Labels": null,
   "Manage Sites": null,
   "Manage asset links": null,
+  "Manage datasets": null,
   "Manage links": null,
   "Manage permissions": null,
   "Manage permissions for adapter ": null,
@@ -671,10 +684,12 @@
   "No export providers found": null,
   "No fields selected.": null,
   "No groups configured": null,
+  "No labels available - Click 'Manage Labels'": null,
   "No linked resources": null,
   "No linked resources found.": null,
   "No live preview available.": null,
   "No location defined for this asset yet.": null,
+  "No more information": null,
   "No nodes selected yet": null,
   "No numeric or boolean fields available.": null,
   "No table rows match the current filter.": null,
@@ -692,6 +707,8 @@
   "Oldest (ascending)": null,
   "Only admins and owners can manage permissions for this resource.": null,
   "Only linked resources are part of the application package.": null,
+  "Open Retention Log": null,
+  "Open fullscreen": null,
   "Optional override for decimal places. Leave empty to show original 
values.": null,
   "Options": null,
   "Order": null,
@@ -794,6 +811,8 @@
   "Remove node": null,
   "Rename file": null,
   "Rename files": null,
+  "Rename the changed fields": null,
+  "Rename the fields with changed data types by using the \"Field Renamer\" 
data processor": null,
   "Repeat password": null,
   "Require users to accept terms after login": null,
   "Reset": null,
@@ -837,6 +856,7 @@
   "Save as template": null,
   "Save changes": null,
   "Save changes?": null,
+  "Save in a new data lake": null,
   "Save pipeline": null,
   "Save template": null,
   "Saving metadata": null,
@@ -853,6 +873,7 @@
   "Secret Key": null,
   "Select Adapter": null,
   "Select All": null,
+  "Select CSV file": null,
   "Select Data": null,
   "Select Fields": null,
   "Select Format": null,
@@ -931,6 +952,8 @@
   "Slide view": null,
   "Slider": null,
   "Slides": null,
+  "Sorry, there are no adapters that are currently idle": null,
+  "Sorry, there are no adapters that are currently running": null,
   "Sorry, there are no pipelines that are currently idle.": null,
   "Sorry, there are no pipelines that are currently running.": null,
   "Sort": null,
@@ -952,6 +975,7 @@
   "Start pipeline immediately": null,
   "Start selected adapters": null,
   "Starting": null,
+  "Starting adapter": null,
   "Starting adapter {{adapterName}}": "Starting adapter {{adapterName}}",
   "Starting pipeline": null,
   "Starting pipeline ": null,
@@ -964,6 +988,7 @@
   "Stop selected adapters": null,
   "Stopped": null,
   "Stopping": null,
+  "Stopping adapter": null,
   "Stopping pipeline": null,
   "Stopping pipeline...": null,
   "Store all events of this source in the internal data store": null,
@@ -1038,6 +1063,8 @@
   "Title": null,
   "Title must not be empty": null,
   "To": null,
+  "To delete a label, please remove the label from all assets": null,
+  "To delete a site, please remove the site from all assets": null,
   "To enable the map view, a map provider needs to be configured. Admins can 
configure map providers under Settings -> Sites.": null,
   "Tooltip": null,
   "Tooltip Content": null,
@@ -1052,7 +1079,9 @@
   "True": null,
   "Truncate Data": null,
   "Truncate data": null,
+  "Truncate the data of the dataset or delete it completely. All historical 
data is lost!": null,
   "Truncating data...": null,
+  "Trust": null,
   "Trying to send test mail...": null,
   "Type": null,
   "Typography": null,
@@ -1060,6 +1089,7 @@
   "Unable to delete all associated pipelines because you are not the owner of 
the following pipelines: ": null,
   "Uninstall": null,
   "Uninstall selected": null,
+  "Uninstalling": null,
   "Unit": null,
   "Unit Transformation": null,
   "Unit conversion": null,
@@ -1072,6 +1102,7 @@
   "Update all changes to dashboard charts or discard current changes.": null,
   "Update asset links": null,
   "Update asset links or close.": null,
+  "Update link": null,
   "Update links": null,
   "Update pipeline": null,
   "Update profile": null,
@@ -1141,7 +1172,9 @@
   "Y": null,
   "Y Label": null,
   "Yes": null,
+  "You are about to start the following adapters:": null,
   "You are about to start the following pipelines:": null,
+  "You are about to stop the following adapters:": null,
   "You are about to stop the following pipelines:": null,
   "You are about to {{ action }} the following elements:": "You are about to 
{{ action }} the following elements:",
   "You can perform a forced stop, which will stop and reset the pipeline 
status.": null,
@@ -1155,9 +1188,11 @@
   "Your password successfully changed.": null,
   "Your recent changes might have altered the data format. Reloading the 
sample ensures you are writing scripts for the most current data. Check your 
transformation rules after the refresh to ensure everything still aligns.": 
null,
   "assets are hidden because no valid location is configured.": null,
+  "available": null,
   "days": null,
   "delete": null,
   "error": null,
+  "install": null,
   "left axis": null,
   "marked as timestamp": null,
   "new filename": null,
@@ -1167,6 +1202,7 @@
   "no log messages available": null,
   "no status information available": null,
   "no stored export providers": null,
+  "not available": null,
   "of": null,
   "or": null,
   "pipeline": null,
@@ -1179,6 +1215,7 @@
   "showing first": null,
   "success": null,
   "to": null,
+  "uninstall": null,
   "visible to registered users": null,
   "waiting": null,
   "will be automatically migrated": null,
diff --git a/ui/deployment/i18n/pl.json b/ui/deployment/i18n/pl.json
index 1da936f97a..b832061a54 100644
--- a/ui/deployment/i18n/pl.json
+++ b/ui/deployment/i18n/pl.json
@@ -29,6 +29,7 @@
   "A label for better readability": "Etykieta, dla lepszej czytelności",
   "A longer description of this asset": "Dłuższy opis tego zasobu",
   "A map visualization for spatial coordinates": "Wizualizacja mapy dla 
współrzędnych przestrzennych",
+  "A measurement field changed to a data type that conflicts with existing 
data. This needs manual adjustments. You can handle this error by following one 
of the given instructions:": "Pole pomiarowe zostało zmienione na typ danych, 
który koliduje z istniejącymi danymi. Wymaga to ręcznych dostosowań. Możesz 
obsłużyć ten błąd, wykonując jedną z podanych instrukcji:",
   "A pie chart that shows the frequency of specific values": "Wykres kołowy 
pokazujący częstość określonych wartości",
   "A short name of the asset": "Krótka nazwa zasobu",
   "A simple chart that shows values on a value/time graph": "Prosty wykres 
pokazujący wartości w funkcji czasu",
@@ -95,6 +96,7 @@
   "Allow self - registration": "Zezwól na samo-rejestrację",
   "Allow self - service password recovery": "Zezwól na samodzielne 
odzyskiwanie hasła",
   "Alternate IDs": "Alternatywne ID",
+  "An unknown error has occurred": "Wystąpił nieznany błąd",
   "Angle where the first slice starts (in degrees).": "Kąt, pod którym zaczyna 
się pierwszy segment (w stopniach).",
   "Angle where the gauge arc begins (in degrees).": "Kąt, pod którym zaczyna 
się łuk wskaźnika (w stopniach).",
   "Angle where the gauge arc ends (in degrees).": "Kąt, pod którym kończy się 
łuk wskaźnika (w stopniach).",
@@ -166,6 +168,7 @@
   "Certificates": "Certyfikaty",
   "Change email": "Zmień e-mail",
   "Change password": "Zmień hasło",
+  "Change the identifier of the \"Data Lake\" by opening the pipeline element 
configuration to save the data in a new \"Data Lake\".": "Zmień identyfikator 
\"Data Lake\", otwierając konfigurację elementu potoku, aby zapisać dane w 
nowym \"Data Lake\".",
   "Change the look and feel of your installation": "Zmień wygląd i styl 
instalacji",
   "Changed": "Zmieniono",
   "Changing the current user's email will require a re-login.": "Zmiana adresu 
e-mail bieżącego użytkownika wymaga ponownego logowania.",
@@ -185,6 +188,7 @@
   "Clear & use simple filters": "Wyczyść i użyj prostych filtrów",
   "Clear Assembly Area": "Wyczyść obszar montażu",
   "Clear selection & reload": "Wyczyść wybór i przeładuj",
+  "Click to add label": "Kliknij, aby dodać etykietę",
   "Click to load": "Kliknij, aby wczytać",
   "Client Secret": "Tajny klucz klienta",
   "Clockwise": "Zgodnie z ruchem wskazówek zegara",
@@ -194,6 +198,7 @@
   "Clone options": "Opcje klonowania",
   "Close": "Zamknij",
   "Code": "Kod",
+  "Collapse preview": "Zwiń podgląd",
   "Color": "Kolor",
   "Color scheme": "Schemat kolorów",
   "Color used above the high threshold.": "Kolor używany powyżej wysokiego 
progu.",
@@ -229,6 +234,7 @@
   "Create asset": "Utwórz zasób",
   "Create asset links": "Utwórz linki zasobu",
   "Create chart": "Utwórz wykres",
+  "Create link": "Utwórz link",
   "Create new API key": "Utwórz nowy klucz API",
   "Create new account": "Utwórz nowe konto",
   "Create new dataset": "Utwórz nowy zbiór danych",
@@ -302,8 +308,11 @@
   "Delete data": "Usuń dane",
   "Delete dataset": "Usuń zbiór danych",
   "Delete file": "Usuń plik",
+  "Delete historical data": "Usuń dane historyczne",
+  "Delete label": "Usuń etykietę",
   "Delete pipeline": "Usuń strumień",
   "Delete service": "Usuń usługę",
+  "Delete site": "Usuń lokalizację",
   "Delete user": "Usuń użytkownika",
   "Deleting data...": "Usuwanie danych...",
   "Deleting pipeline...": "Usuwanie strumienia...",
@@ -398,6 +407,7 @@
   "Exit fullscreen": "Wyjdź z trybu pełnoekranowego",
   "Expand Less": "Zwiń",
   "Expand More": "Rozwiń",
+  "Expand preview": "Rozwiń podgląd",
   "Expires": "Wygasa",
   "Export": "Eksportuj",
   "Export Data": "Eksportuj dane",
@@ -409,6 +419,7 @@
   "Export resources": "Eksportuj zasoby",
   "Exported items {{assetName}}": "Wyeksportowane elementy {{assetName}}",
   "Exporting resources...": "Eksportowanie zasobów...",
+  "Fail": "Niepowodzenie",
   "False": "Fałsz",
   "Field": "Pole",
   "Field Name": "Nazwa pola",
@@ -512,6 +523,7 @@
   "Install the following pipeline elements and start the tutorial again:": 
"Zainstaluj następujące elementy strumienia i uruchom samouczek ponownie:",
   "Installation": "Instalacja",
   "Installed": "Zainstalowane",
+  "Installing": "Instalowanie",
   "Internally managed by {{appName}}": "Zarządzane wewnętrznie przez 
{{appName}}",
   "Interval [sec]": "Interwał [s]",
   "Interval in seconds in which an event must arrive": "Interwał w sekundach, 
w którym musi nadejść zdarzenie",
@@ -589,6 +601,7 @@
   "Manage Labels": "Zarządzaj etykietami",
   "Manage Sites": "Zarządzaj lokalizacjami",
   "Manage asset links": "Zarządzaj linkami zasobu",
+  "Manage datasets": "Zarządzaj zestawami danych",
   "Manage links": "Zarządzaj linkami",
   "Manage permissions": "Zarządzaj uprawnieniami",
   "Manage permissions for adapter ": "Zarządzaj uprawnieniami dla adaptera ",
@@ -671,10 +684,12 @@
   "No export providers found": "Nie znaleziono exportera",
   "No fields selected.": "Nie wybrano żadnych pól.",
   "No groups configured": "Nie skonfigurowano grup",
+  "No labels available - Click 'Manage Labels'": "Brak dostępnych etykiet - 
kliknij 'Zarządzaj etykietami'",
   "No linked resources": "Brak powiązanych zasobów",
   "No linked resources found.": "Nie znaleziono powiązanych zasobów.",
   "No live preview available.": "Brak dostępnego podglądu na żywo.",
   "No location defined for this asset yet.": "Dla tego zasobu nie zdefiniowano 
jeszcze lokalizacji.",
+  "No more information": "Brak dalszych informacji",
   "No nodes selected yet": "Nie wybrano jeszcze żadnych węzłów",
   "No numeric or boolean fields available.": "Brak dostępnych pól liczbowych 
lub logicznych.",
   "No table rows match the current filter.": "Żaden wiersz tabeli nie pasuje 
do bieżącego filtra.",
@@ -692,6 +707,8 @@
   "Oldest (ascending)": "Najstarsze (rosnąco)",
   "Only admins and owners can manage permissions for this resource.": "Tylko 
administratorzy i właściciele mogą zarządzać uprawnieniami do tego zasobu.",
   "Only linked resources are part of the application package.": "Tylko 
powiązane zasoby są częścią pakietu aplikacji.",
+  "Open Retention Log": "Otwórz dziennik retencji",
+  "Open fullscreen": "Otwórz pełny ekran",
   "Optional override for decimal places. Leave empty to show original 
values.": "Opcjonalne nadpisanie liczby miejsc dziesiętnych. Pozostaw puste, 
aby pokazać wartości oryginalne.",
   "Options": "Opcje",
   "Order": "Kolejność",
@@ -794,6 +811,8 @@
   "Remove node": "Usuń węzeł",
   "Rename file": "Zmień nazwę pliku",
   "Rename files": "Zmień nazwy plików",
+  "Rename the changed fields": "Zmień nazwy zmienionych pól",
+  "Rename the fields with changed data types by using the \"Field Renamer\" 
data processor": "Zmień nazwy pól ze zmienionymi typami danych za pomocą 
procesora danych \"Field Renamer\"",
   "Repeat password": "Powtórz hasło",
   "Require users to accept terms after login": "Wymagaj zaakceptowania 
warunków po zalogowaniu",
   "Reset": "Resetuj",
@@ -837,6 +856,7 @@
   "Save as template": "Zapisz jako szablon",
   "Save changes": "Zapisz zmiany",
   "Save changes?": "Zapisać zmiany?",
+  "Save in a new data lake": "Zapisz w nowym Data Lake",
   "Save pipeline": "Zapisz strumień",
   "Save template": "Zapisz szablon",
   "Saving metadata": "Zapisywanie metadanych",
@@ -853,6 +873,7 @@
   "Secret Key": "Klucz tajny",
   "Select Adapter": "Wybierz adapter",
   "Select All": "Zaznacz wszystko",
+  "Select CSV file": "Wybierz plik CSV",
   "Select Data": "Wybierz dane",
   "Select Fields": "Wybierz pola",
   "Select Format": "Wybierz format",
@@ -931,6 +952,8 @@
   "Slide view": "Widok slajdów",
   "Slider": "Suwak",
   "Slides": "Slajdy",
+  "Sorry, there are no adapters that are currently idle": "Przepraszamy, 
obecnie nie ma bezczynnych adapterów",
+  "Sorry, there are no adapters that are currently running": "Przepraszamy, 
obecnie nie ma uruchomionych adapterów",
   "Sorry, there are no pipelines that are currently idle.": "Niestety, obecnie 
nie ma strumieni w stanie zatrzymania.",
   "Sorry, there are no pipelines that are currently running.": "Niestety, 
obecnie nie ma uruchomionych strumieni.",
   "Sort": "Sortuj",
@@ -952,6 +975,7 @@
   "Start pipeline immediately": "Uruchom strumień od razu",
   "Start selected adapters": "Uruchom wybrane adaptery",
   "Starting": "Uruchamianie",
+  "Starting adapter": "Uruchamianie adaptera",
   "Starting adapter {{adapterName}}": "Uruchamianie adaptera {{adapterName}}",
   "Starting pipeline": "Uruchamianie strumienia",
   "Starting pipeline ": "Uruchamianie strumienia",
@@ -964,6 +988,7 @@
   "Stop selected adapters": "Zatrzymaj wybrane adaptery",
   "Stopped": "Zatrzymany",
   "Stopping": "Zatrzymywanie",
+  "Stopping adapter": "Zatrzymywanie adaptera",
   "Stopping pipeline": "Zatrzymywanie strumienia",
   "Stopping pipeline...": "Zatrzymywanie strumienia...",
   "Store all events of this source in the internal data store": "Przechowuj 
wszystkie zdarzenia z tego źródła w wewnętrznej bazie danych",
@@ -1038,6 +1063,8 @@
   "Title": "Tytuł",
   "Title must not be empty": "Tytuł nie może być pusty",
   "To": "Do",
+  "To delete a label, please remove the label from all assets": "Aby usunąć 
etykietę, usuń ją ze wszystkich zasobów",
+  "To delete a site, please remove the site from all assets": "Aby usunąć 
lokalizację, usuń ją ze wszystkich zasobów",
   "To enable the map view, a map provider needs to be configured. Admins can 
configure map providers under Settings -> Sites.": "Aby włączyć widok mapy, 
należy skonfigurować dostawcę map. Administratorzy mogą to zrobić w Ustawienia 
-> Lokalizacje.",
   "Tooltip": "Podpowiedź",
   "Tooltip Content": "Zawartość podpowiedzi",
@@ -1052,7 +1079,9 @@
   "True": "Prawda",
   "Truncate Data": "Wyczyść dane",
   "Truncate data": "Wyczyść dane",
+  "Truncate the data of the dataset or delete it completely. All historical 
data is lost!": "Skróć dane zestawu danych lub usuń go całkowicie. Wszystkie 
dane historyczne zostaną utracone!",
   "Truncating data...": "Czyszczenie danych...",
+  "Trust": "Zaufaj",
   "Trying to send test mail...": "Próba wysłania wiadomości testowej...",
   "Type": "Typ",
   "Typography": "Typografia",
@@ -1060,6 +1089,7 @@
   "Unable to delete all associated pipelines because you are not the owner of 
the following pipelines: ": "Nie można usunąć wszystkich powiązanych strumieni, 
ponieważ nie jesteś właścicielem następujących strumieni: ",
   "Uninstall": "Odinstaluj",
   "Uninstall selected": "Odinstaluj wybrane",
+  "Uninstalling": "Odinstalowywanie",
   "Unit": "Jednostka",
   "Unit Transformation": "Transformacja jednostek",
   "Unit conversion": "Konwersja jednostek",
@@ -1072,6 +1102,7 @@
   "Update all changes to dashboard charts or discard current changes.": 
"Zapisz wszystkie zmiany wykresów pulpitu lub odrzuć bieżące zmiany.",
   "Update asset links": "Zaktualizuj linki zasobu",
   "Update asset links or close.": "Zaktualizuj powiązania zasobów lub 
zamknij.",
+  "Update link": "Zaktualizuj link",
   "Update links": "Zaktualizuj linki",
   "Update pipeline": "Zaktualizuj strumień",
   "Update profile": "Zaktualizuj profil",
@@ -1141,7 +1172,9 @@
   "Y": "Y",
   "Y Label": "Etykieta Y",
   "Yes": "Tak",
+  "You are about to start the following adapters:": "Zamierzasz uruchomić 
następujące adaptery:",
   "You are about to start the following pipelines:": "Zamierzasz uruchomić 
następujące strumienie:",
+  "You are about to stop the following adapters:": "Zamierzasz zatrzymać 
następujące adaptery:",
   "You are about to stop the following pipelines:": "Zamierzasz zatrzymać 
następujące strumienie:",
   "You are about to {{ action }} the following elements:": "Zamierzasz {{ 
action }} następujące elementy:",
   "You can perform a forced stop, which will stop and reset the pipeline 
status.": "Możesz wymusić zatrzymanie, które zatrzyma i zresetuje status 
strumienia.",
@@ -1155,9 +1188,11 @@
   "Your password successfully changed.": "Twoje hasło zostało pomyślnie 
zmienione.",
   "Your recent changes might have altered the data format. Reloading the 
sample ensures you are writing scripts for the most current data. Check your 
transformation rules after the refresh to ensure everything still aligns.": 
"Twoje ostatnie zmiany mogły zmienić format danych. Ponowne wczytanie próbki 
zapewnia, że piszesz skrypty dla najnowszych danych. Po odświeżeniu sprawdź 
reguły transformacji, aby upewnić się, że wszystko nadal pasuje.",
   "assets are hidden because no valid location is configured.": "Zasoby są 
ukryte, ponieważ nie skonfigurowano prawidłowej lokalizacji.",
+  "available": "dostępne",
   "days": "dni",
   "delete": "usuń",
   "error": "błąd",
+  "install": "zainstaluj",
   "left axis": "lewa oś",
   "marked as timestamp": "oznaczone jako znacznik czasu",
   "new filename": "nowa nazwa pliku",
@@ -1167,6 +1202,7 @@
   "no log messages available": "brak dostępnych logów",
   "no status information available": "brak informacji o statusie",
   "no stored export providers": "brak zapisanych eksporterów",
+  "not available": "niedostępne",
   "of": "z",
   "or": "lub",
   "pipeline": "strumień",
@@ -1179,6 +1215,7 @@
   "showing first": "pokazywanie pierwszych",
   "success": "sukces",
   "to": "do",
+  "uninstall": "odinstaluj",
   "visible to registered users": "widoczne dla zarejestrowanych użytkowników",
   "waiting": "oczekiwanie",
   "will be automatically migrated": "zostaną automatycznie zmigrowane",
diff --git a/ui/package-lock.json b/ui/package-lock.json
index 7f33f0e25d..c3299ca290 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -86,7 +86,7 @@
         "@types/supercluster": "^7.1.3",
         "@typescript-eslint/eslint-plugin": "^8.46.1",
         "@typescript-eslint/parser": "^8.32.1",
-        "@vendure/ngx-translate-extract": "^9.4.0",
+        "@vendure/ngx-translate-extract": "^10.1.3",
         "ajv-keywords": "^5.1.0",
         "assert": "^2.1.0",
         "csv-string": "^4.1.1",
@@ -3553,6 +3553,7 @@
       "integrity": 
"sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
       "devOptional": true,
       "license": "ISC",
+      "peer": true,
       "dependencies": {
         "string-width": "^5.1.2",
         "string-width-cjs": "npm:string-width@^4.2.0",
@@ -3571,6 +3572,7 @@
       "integrity": 
"sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
       "devOptional": true,
       "license": "MIT",
+      "peer": true,
       "engines": {
         "node": ">=12"
       },
@@ -3584,6 +3586,7 @@
       "integrity": 
"sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
       "devOptional": true,
       "license": "MIT",
+      "peer": true,
       "engines": {
         "node": ">=12"
       },
@@ -3596,7 +3599,8 @@
       "resolved": 
"https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz";,
       "integrity": 
"sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
       "devOptional": true,
-      "license": "MIT"
+      "license": "MIT",
+      "peer": true
     },
     "node_modules/@isaacs/cliui/node_modules/string-width": {
       "version": "5.1.2",
@@ -3604,6 +3608,7 @@
       "integrity": 
"sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
       "devOptional": true,
       "license": "MIT",
+      "peer": true,
       "dependencies": {
         "eastasianwidth": "^0.2.0",
         "emoji-regex": "^9.2.2",
@@ -3622,6 +3627,7 @@
       "integrity": 
"sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
       "devOptional": true,
       "license": "MIT",
+      "peer": true,
       "dependencies": {
         "ansi-regex": "^6.0.1"
       },
@@ -3638,6 +3644,7 @@
       "integrity": 
"sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
       "devOptional": true,
       "license": "MIT",
+      "peer": true,
       "dependencies": {
         "ansi-styles": "^6.1.0",
         "string-width": "^5.0.1",
@@ -5195,17 +5202,17 @@
       "optional": true
     },
     "node_modules/@phenomnomnominal/tsquery": {
-      "version": "6.1.3",
-      "resolved": 
"https://registry.npmjs.org/@phenomnomnominal/tsquery/-/tsquery-6.1.3.tgz";,
-      "integrity": 
"sha512-CEqpJ872StsxRmwv9ePCZ4BCisrJSlREUC5XxIRYxhvODt4aQoJFFmjTgaP6meyKiiXxxN/VWPZ58j4yHXRkmw==",
+      "version": "6.2.0",
+      "resolved": 
"https://registry.npmjs.org/@phenomnomnominal/tsquery/-/tsquery-6.2.0.tgz";,
+      "integrity": 
"sha512-Vo9nkhfZxDB/sBiqIY3pjDC4mOSyure+AFlEW5hcy/tRE82MqCXjRN4InnVNMldinRt0dLYqg4HAU2XPq5e1LA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@types/esquery": "^1.5.0",
-        "esquery": "^1.5.0"
+        "@types/esquery": "^1.5.4",
+        "esquery": "^1.7.0"
       },
       "peerDependencies": {
-        "typescript": "^3 || ^4 || ^5"
+        "typescript": ">3.0.0"
       }
     },
     "node_modules/@pkgjs/parseargs": {
@@ -5215,6 +5222,7 @@
       "dev": true,
       "license": "MIT",
       "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=14"
       }
@@ -6698,20 +6706,6 @@
       "dev": true,
       "license": "MIT"
     },
-    "node_modules/@types/strip-bom": {
-      "version": "3.0.0",
-      "resolved": 
"https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz";,
-      "integrity": 
"sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/@types/strip-json-comments": {
-      "version": "0.0.30",
-      "resolved": 
"https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz";,
-      "integrity": 
"sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==",
-      "dev": true,
-      "license": "MIT"
-    },
     "node_modules/@types/supercluster": {
       "version": "7.1.3",
       "resolved": 
"https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.3.tgz";,
@@ -6987,32 +6981,241 @@
       }
     },
     "node_modules/@vendure/ngx-translate-extract": {
-      "version": "9.4.0",
-      "resolved": 
"https://registry.npmjs.org/@vendure/ngx-translate-extract/-/ngx-translate-extract-9.4.0.tgz";,
-      "integrity": 
"sha512-2+Blsm33Ub3cQ0K6dLQWlCg3QfHJIvkUS7vovq39At+lU+VSqMNvVpRkqNrsV9sTpYeyZzVtGOqHW5Xa1YwkAw==",
+      "version": "10.1.3",
+      "resolved": 
"https://registry.npmjs.org/@vendure/ngx-translate-extract/-/ngx-translate-extract-10.1.3.tgz";,
+      "integrity": 
"sha512-HhtNWNc99UoOiWH5lda0gxAW0XTfASkRxQRwZ/bU9GiXMInTJxP38ouP4s/p04nivdZu5jJ/nimOxEN1TSulCw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@phenomnomnominal/tsquery": "^6.1.3",
-        "braces": "^3.0.2",
-        "colorette": "^2.0.20",
+        "@phenomnomnominal/tsquery": "^6.1.4",
+        "braces": "^3.0.3",
         "flat": "^6.0.1",
-        "gettext-parser": "^4.2.0",
-        "glob": "^10.3.0",
-        "json5": "^2.2.3",
-        "tsconfig": "^7.0.0",
-        "yargs": "^17.7.2"
+        "gettext-parser": "^9.0.0",
+        "glob": "^13.0.0",
+        "yargs": "^18.0.0"
       },
       "bin": {
-        "ngx-translate-extract": "bin/cli.js"
+        "ngx-translate-extract": "cli.js"
       },
       "engines": {
-        "node": ">=18.13.0",
-        "npm": ">=8"
+        "node": ">=20.19.0",
+        "npm": ">=10"
       },
       "peerDependencies": {
-        "@angular/compiler": ">=17.0.0",
-        "typescript": ">=5.2.0"
+        "@angular/compiler": ">=20.0.0",
+        "typescript": ">=5.8.0"
+      }
+    },
+    "node_modules/@vendure/ngx-translate-extract/node_modules/ansi-regex": {
+      "version": "6.2.2",
+      "resolved": 
"https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz";,
+      "integrity": 
"sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-regex?sponsor=1";
+      }
+    },
+    "node_modules/@vendure/ngx-translate-extract/node_modules/ansi-styles": {
+      "version": "6.2.3",
+      "resolved": 
"https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz";,
+      "integrity": 
"sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1";
+      }
+    },
+    "node_modules/@vendure/ngx-translate-extract/node_modules/balanced-match": 
{
+      "version": "4.0.4",
+      "resolved": 
"https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz";,
+      "integrity": 
"sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "18 || 20 || >=22"
+      }
+    },
+    
"node_modules/@vendure/ngx-translate-extract/node_modules/brace-expansion": {
+      "version": "5.0.6",
+      "resolved": 
"https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz";,
+      "integrity": 
"sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^4.0.2"
+      },
+      "engines": {
+        "node": "18 || 20 || >=22"
+      }
+    },
+    "node_modules/@vendure/ngx-translate-extract/node_modules/cliui": {
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz";,
+      "integrity": 
"sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "string-width": "^7.2.0",
+        "strip-ansi": "^7.1.0",
+        "wrap-ansi": "^9.0.0"
+      },
+      "engines": {
+        "node": ">=20"
+      }
+    },
+    "node_modules/@vendure/ngx-translate-extract/node_modules/emoji-regex": {
+      "version": "10.6.0",
+      "resolved": 
"https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz";,
+      "integrity": 
"sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@vendure/ngx-translate-extract/node_modules/glob": {
+      "version": "13.0.6",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz";,
+      "integrity": 
"sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "dependencies": {
+        "minimatch": "^10.2.2",
+        "minipass": "^7.1.3",
+        "path-scurry": "^2.0.2"
+      },
+      "engines": {
+        "node": "18 || 20 || >=22"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs";
+      }
+    },
+    "node_modules/@vendure/ngx-translate-extract/node_modules/lru-cache": {
+      "version": "11.3.6",
+      "resolved": 
"https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.6.tgz";,
+      "integrity": 
"sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "engines": {
+        "node": "20 || >=22"
+      }
+    },
+    "node_modules/@vendure/ngx-translate-extract/node_modules/minimatch": {
+      "version": "10.2.5",
+      "resolved": 
"https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz";,
+      "integrity": 
"sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "dependencies": {
+        "brace-expansion": "^5.0.5"
+      },
+      "engines": {
+        "node": "18 || 20 || >=22"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs";
+      }
+    },
+    "node_modules/@vendure/ngx-translate-extract/node_modules/path-scurry": {
+      "version": "2.0.2",
+      "resolved": 
"https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz";,
+      "integrity": 
"sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "dependencies": {
+        "lru-cache": "^11.0.0",
+        "minipass": "^7.1.2"
+      },
+      "engines": {
+        "node": "18 || 20 || >=22"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs";
+      }
+    },
+    "node_modules/@vendure/ngx-translate-extract/node_modules/string-width": {
+      "version": "7.2.0",
+      "resolved": 
"https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz";,
+      "integrity": 
"sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "emoji-regex": "^10.3.0",
+        "get-east-asian-width": "^1.0.0",
+        "strip-ansi": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus";
+      }
+    },
+    "node_modules/@vendure/ngx-translate-extract/node_modules/strip-ansi": {
+      "version": "7.2.0",
+      "resolved": 
"https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz";,
+      "integrity": 
"sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^6.2.2"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/strip-ansi?sponsor=1";
+      }
+    },
+    "node_modules/@vendure/ngx-translate-extract/node_modules/wrap-ansi": {
+      "version": "9.0.2",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz";,
+      "integrity": 
"sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-styles": "^6.2.1",
+        "string-width": "^7.0.0",
+        "strip-ansi": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1";
+      }
+    },
+    "node_modules/@vendure/ngx-translate-extract/node_modules/yargs": {
+      "version": "18.0.0",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz";,
+      "integrity": 
"sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "cliui": "^9.0.1",
+        "escalade": "^3.1.1",
+        "get-caller-file": "^2.0.5",
+        "string-width": "^7.2.0",
+        "y18n": "^5.0.5",
+        "yargs-parser": "^22.0.0"
+      },
+      "engines": {
+        "node": "^20.19.0 || ^22.12.0 || >=23"
+      }
+    },
+    "node_modules/@vendure/ngx-translate-extract/node_modules/yargs-parser": {
+      "version": "22.0.0",
+      "resolved": 
"https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz";,
+      "integrity": 
"sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": "^20.19.0 || ^22.12.0 || >=23"
       }
     },
     "node_modules/@yarnpkg/lockfile": {
@@ -8296,6 +8499,7 @@
       "integrity": 
"sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
       "devOptional": true,
       "license": "ISC",
+      "peer": true,
       "dependencies": {
         "string-width": "^4.2.0",
         "strip-ansi": "^6.0.1",
@@ -8311,6 +8515,7 @@
       "integrity": 
"sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
       "devOptional": true,
       "license": "MIT",
+      "peer": true,
       "dependencies": {
         "ansi-styles": "^4.0.0",
         "string-width": "^4.1.0",
@@ -9790,7 +9995,8 @@
       "resolved": 
"https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz";,
       "integrity": 
"sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
       "devOptional": true,
-      "license": "MIT"
+      "license": "MIT",
+      "peer": true
     },
     "node_modules/ecc-jsbn": {
       "version": "0.1.2",
@@ -10377,9 +10583,9 @@
       }
     },
     "node_modules/esquery": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz";,
-      "integrity": 
"sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz";,
+      "integrity": 
"sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==",
       "dev": true,
       "license": "BSD-3-Clause",
       "dependencies": {
@@ -11138,6 +11344,7 @@
       "integrity": 
"sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
       "devOptional": true,
       "license": "ISC",
+      "peer": true,
       "dependencies": {
         "cross-spawn": "^7.0.0",
         "signal-exit": "^4.0.1"
@@ -11355,16 +11562,17 @@
       }
     },
     "node_modules/gettext-parser": {
-      "version": "4.2.0",
-      "resolved": 
"https://registry.npmjs.org/gettext-parser/-/gettext-parser-4.2.0.tgz";,
-      "integrity": 
"sha512-aMgPyjC9W5Mz9tbFU8DcQ7GYMXoFWq633kaWGt4imlcpBWzDIWk7HY7nCSZTCJxyjRaLq9L/NEjMKkZ9gR630Q==",
+      "version": "9.0.2",
+      "resolved": 
"https://registry.npmjs.org/gettext-parser/-/gettext-parser-9.0.2.tgz";,
+      "integrity": 
"sha512-dGvq3S1gpS6e9KzNkwgPED5xxfWk7mNYzzdi/fPdJF5qS7B+yo8El2ZQyyhJ79PyzTtHbwiqYOFsqBdzbQ0GPg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "content-type": "^1.0.4",
-        "encoding": "^0.1.13",
-        "readable-stream": "^3.6.0",
-        "safe-buffer": "^5.2.1"
+        "content-type": "^1.0.5",
+        "encoding": "^0.1.13"
+      },
+      "engines": {
+        "node": ">=20"
       }
     },
     "node_modules/gl-matrix": {
@@ -11380,6 +11588,7 @@
       "deprecated": "Old versions of glob are not supported, and contain 
widely publicized security vulnerabilities, which have been fixed in the 
current version. Please update. Support for old versions may be purchased (at 
exorbitant rates) by contacting [email protected]",
       "devOptional": true,
       "license": "ISC",
+      "peer": true,
       "dependencies": {
         "foreground-child": "^3.1.0",
         "jackspeak": "^3.1.2",
@@ -12507,6 +12716,7 @@
       "integrity": 
"sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
       "devOptional": true,
       "license": "BlueOak-1.0.0",
+      "peer": true,
       "dependencies": {
         "@isaacs/cliui": "^8.0.2"
       },
@@ -15779,7 +15989,8 @@
       "resolved": 
"https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz";,
       "integrity": 
"sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
       "devOptional": true,
-      "license": "BlueOak-1.0.0"
+      "license": "BlueOak-1.0.0",
+      "peer": true
     },
     "node_modules/package-manager-detector": {
       "version": "1.6.0",
@@ -15979,6 +16190,7 @@
       "integrity": 
"sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
       "devOptional": true,
       "license": "BlueOak-1.0.0",
+      "peer": true,
       "dependencies": {
         "lru-cache": "^10.2.0",
         "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
@@ -15995,7 +16207,8 @@
       "resolved": 
"https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz";,
       "integrity": 
"sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
       "devOptional": true,
-      "license": "ISC"
+      "license": "ISC",
+      "peer": true
     },
     "node_modules/path-to-regexp": {
       "version": "8.4.2",
@@ -17705,6 +17918,7 @@
       "integrity": 
"sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
       "devOptional": true,
       "license": "MIT",
+      "peer": true,
       "dependencies": {
         "emoji-regex": "^8.0.0",
         "is-fullwidth-code-point": "^3.0.0",
@@ -17720,6 +17934,7 @@
       "integrity": 
"sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
       "devOptional": true,
       "license": "MIT",
+      "peer": true,
       "engines": {
         "node": ">=8"
       }
@@ -17754,6 +17969,7 @@
       "integrity": 
"sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
       "devOptional": true,
       "license": "MIT",
+      "peer": true,
       "dependencies": {
         "ansi-regex": "^5.0.1"
       },
@@ -17761,16 +17977,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/strip-bom": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz";,
-      "integrity": 
"sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/strip-final-newline": {
       "version": "2.0.0",
       "resolved": 
"https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz";,
@@ -18016,29 +18222,6 @@
         "node": ">=6.10"
       }
     },
-    "node_modules/tsconfig": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz";,
-      "integrity": 
"sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@types/strip-bom": "^3.0.0",
-        "@types/strip-json-comments": "0.0.30",
-        "strip-bom": "^3.0.0",
-        "strip-json-comments": "^2.0.0"
-      }
-    },
-    "node_modules/tsconfig/node_modules/strip-json-comments": {
-      "version": "2.0.1",
-      "resolved": 
"https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz";,
-      "integrity": 
"sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/tslib": {
       "version": "2.8.1",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz";,
@@ -18477,6 +18660,7 @@
       "integrity": 
"sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
       "devOptional": true,
       "license": "MIT",
+      "peer": true,
       "dependencies": {
         "ansi-styles": "^4.0.0",
         "string-width": "^4.1.0",
@@ -18556,6 +18740,7 @@
       "integrity": 
"sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
       "devOptional": true,
       "license": "MIT",
+      "peer": true,
       "dependencies": {
         "cliui": "^8.0.1",
         "escalade": "^3.1.1",
@@ -18575,6 +18760,7 @@
       "integrity": 
"sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
       "devOptional": true,
       "license": "ISC",
+      "peer": true,
       "engines": {
         "node": ">=12"
       }
diff --git a/ui/package.json b/ui/package.json
index 2a0ff79e3f..06a02ce192 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -14,7 +14,7 @@
     "start": "npm run build-libraries && node ./deployment/prebuild.js && ng 
serve -o",
     "test": "node ./deployment/prebuild.js && npm run build-libraries && ng 
test",
     "run-prebuild-script": "node ./deployment/prebuild.js",
-    "build": "node ./deployment/prebuild.js && set 
NODE_OPTIONS=--max-old-space-size=8192 && npm run build-libraries && ng build 
--configuration production",
+    "build": "npm run i18n:validate && node ./deployment/prebuild.js && set 
NODE_OPTIONS=--max-old-space-size=8192 && npm run build-libraries && ng build 
--configuration production",
     "build-dev": "node ./deployment/prebuild.js && set 
NODE_OPTIONS=--max-old-space-size=8192 && npm run build-libraries && ng build",
     "lint": "ng lint app && ng lint app-e2e && ng lint 
@streampipes/platform-services && ng lint @streampipes/shared-ui",
     "lint:fix": "ng lint app --fix && ng lint app-e2e --fix && ng lint 
@streampipes/platform-services --fix && ng lint @streampipes/shared-ui --fix",
@@ -26,7 +26,9 @@
     "test-cypress-all": "npx cypress run --spec 'cypress/tests/**/*.spec.ts' 
--config baseUrl=http://localhost:8082";,
     "prepare": "cd ../ && husky install ./ui/.husky",
     "i18n:extract": "ngx-translate-extract --input ./src --input ./projects 
--output ./deployment/i18n/{en,de,pl}.json -n -s --clean --format json",
-    "i18n:translate": "node ./deployment/i18n-translate.js"
+    "i18n:translate": "node ./deployment/i18n-translate.js",
+    "i18n:validate": "node ./deployment/i18n-validate.js",
+    "i18n:check": "npm run i18n:extract && prettier --write 
./deployment/i18n/{en,de,pl}.json && npm run i18n:validate"
   },
   "dependencies": {
     "@angular/animations": "^21.2.12",
@@ -107,7 +109,7 @@
     "@types/showdown": "2.0.6",
     "@typescript-eslint/eslint-plugin": "^8.46.1",
     "@typescript-eslint/parser": "^8.32.1",
-    "@vendure/ngx-translate-extract": "^9.4.0",
+    "@vendure/ngx-translate-extract": "^10.1.3",
     "ajv-keywords": "^5.1.0",
     "assert": "^2.1.0",
     "csv-string": "^4.1.1",

Reply via email to