iobroker.parcelapp 0.8.0 → 0.10.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/README.md +33 -16
- package/admin/i18n/de.json +11 -3
- package/admin/i18n/en.json +11 -3
- package/admin/i18n/es.json +11 -3
- package/admin/i18n/fr.json +11 -3
- package/admin/i18n/it.json +11 -3
- package/admin/i18n/nl.json +11 -3
- package/admin/i18n/pl.json +11 -3
- package/admin/i18n/pt.json +11 -3
- package/admin/i18n/ru.json +11 -3
- package/admin/i18n/uk.json +11 -3
- package/admin/i18n/zh-cn.json +11 -3
- package/admin/jsonConfig.json +0 -4
- package/build/lib/coerce.js +7 -2
- package/build/lib/coerce.js.map +2 -2
- package/build/lib/i18n.js +29 -2
- package/build/lib/i18n.js.map +2 -2
- package/build/lib/parcel-client.js +117 -33
- package/build/lib/parcel-client.js.map +3 -3
- package/build/lib/state-manager.js +149 -128
- package/build/lib/state-manager.js.map +2 -2
- package/build/lib/types.js +3 -131
- package/build/lib/types.js.map +2 -2
- package/build/main.js +309 -159
- package/build/main.js.map +2 -2
- package/io-package.json +28 -28
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -45,7 +45,7 @@ For details and how to disable it, see the [Sentry plugin documentation](https:/
|
|
|
45
45
|
| Option | Description | Default |
|
|
46
46
|
| ------------------------- | ---------------------------------------------------------------------------------------------------------- | ------- |
|
|
47
47
|
| **API Key** | Your parcel.app API key (get it at [web.parcelapp.net](https://web.parcelapp.net)) | — |
|
|
48
|
-
| **Poll Interval** | How often to fetch updates (minutes)
|
|
48
|
+
| **Poll Interval** | How often to fetch updates (minutes). parcel.app serves the list from a ~45–90 min server cache, so shorter intervals mostly reduce the delay until a refresh is noticed. | 10 |
|
|
49
49
|
| **Auto-remove delivered** | Remove delivered packages from states automatically. When disabled, they stay until deleted in parcel.app. | Yes |
|
|
50
50
|
|
|
51
51
|
Status labels (`Delivered`, `In Transit`, …) and delivery estimates (`today`, `tomorrow`, `in X days`) are rendered in the ioBroker system language.
|
|
@@ -65,7 +65,7 @@ parcelapp.0.
|
|
|
65
65
|
└── {packageId}. — One device per package
|
|
66
66
|
├── carrier — Carrier name (e.g. DHL Express)
|
|
67
67
|
├── status — Status text (e.g. In Transit)
|
|
68
|
-
├── statusCode — Status code (0-8)
|
|
68
|
+
├── statusCode — Status code (0-8, -1 = unknown)
|
|
69
69
|
├── description — Package description
|
|
70
70
|
├── trackingNumber — Tracking number
|
|
71
71
|
├── extraInfo — Extra information (postal code, email)
|
|
@@ -73,9 +73,19 @@ parcelapp.0.
|
|
|
73
73
|
├── deliveryEstimate — Human-readable estimate (today, tomorrow)
|
|
74
74
|
├── lastEvent — Latest tracking event
|
|
75
75
|
├── lastLocation — Last known location
|
|
76
|
-
└── lastUpdated —
|
|
76
|
+
└── lastUpdated — Timestamp of the last tracking-data change
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
+
**Status codes** (`statusCode` — the primary datapoint for automations):
|
|
80
|
+
|
|
81
|
+
| Code | Meaning | Code | Meaning |
|
|
82
|
+
| ---- | --------------- | ---- | ----------------------- |
|
|
83
|
+
| 0 | Delivered | 5 | Not Found |
|
|
84
|
+
| 1 | Frozen | 6 | Delivery Attempt Failed |
|
|
85
|
+
| 2 | In Transit | 7 | Exception |
|
|
86
|
+
| 3 | Awaiting Pickup | 8 | Info Received |
|
|
87
|
+
| 4 | Out for Delivery | -1 | Unknown (unexpected API value — package stays visible) |
|
|
88
|
+
|
|
79
89
|
---
|
|
80
90
|
|
|
81
91
|
## Add Deliveries via Script
|
|
@@ -93,11 +103,12 @@ sendTo("parcelapp.0", "addDelivery", {
|
|
|
93
103
|
});
|
|
94
104
|
```
|
|
95
105
|
|
|
96
|
-
`tracking_number`, `carrier_code` and `description` are required; `language` and `send_push_confirmation` are optional. The delivery is added to your parcel.app account and a poll
|
|
106
|
+
`tracking_number`, `carrier_code` and `description` are required; `language` and `send_push_confirmation` are optional. The delivery is added to your parcel.app account and a poll follows right away (at most one poll per minute) — but freshly added deliveries usually have no tracking data yet (see the note below).
|
|
97
107
|
|
|
98
108
|
**Notes:**
|
|
99
109
|
|
|
100
110
|
- **POST rate limit: 20 deliveries per day** — failed attempts (e.g. wrong `carrier_code`) also count against this limit.
|
|
111
|
+
- **Each field may be at most 512 characters**, and the adapter accepts at most **20 addDelivery calls per minute** — beyond either limit the call returns `success: false` with an explanatory `error_message` instead of reaching parcel.app.
|
|
101
112
|
- Fresh deliveries usually have no tracking events for **45–90 minutes** after they are added. That's a parcel.app-side delay, not an adapter issue.
|
|
102
113
|
- **Deleting packages is only possible in the parcel.app app/web UI** — the API has no delete endpoint. With `autoRemoveDelivered` enabled, the adapter still drops delivered packages from ioBroker states automatically.
|
|
103
114
|
|
|
@@ -113,7 +124,7 @@ sendTo("parcelapp.0", "addDelivery", {
|
|
|
113
124
|
|
|
114
125
|
### No deliveries shown
|
|
115
126
|
|
|
116
|
-
- The API returns cached data — new deliveries
|
|
127
|
+
- The API returns cached data — new deliveries and fresh tracking events can take **45–90 minutes** to appear (parcel.app-side cache)
|
|
117
128
|
- Check if you have active deliveries in the parcel.app
|
|
118
129
|
|
|
119
130
|
### Rate limit
|
|
@@ -129,12 +140,28 @@ sendTo("parcelapp.0", "addDelivery", {
|
|
|
129
140
|
Placeholder for the next version (at the beginning of the line):
|
|
130
141
|
### **WORK IN PROGRESS**
|
|
131
142
|
-->
|
|
143
|
+
### 0.10.0 (2026-07-08)
|
|
144
|
+
|
|
145
|
+
- Fixed: the admin "Test Connection" button now reports real failures — before, it always showed "Ok" even with a wrong API key.
|
|
146
|
+
- Fixed: a package's last-updated timestamp no longer jumps to the restart time after an adapter restart — it only changes when tracking data actually changed.
|
|
147
|
+
- Fixed: a stalled API response can no longer freeze polling until a manual restart — every request now has a hard 60-second deadline.
|
|
148
|
+
- Fixed: a failed adapter start now triggers an automatic restart instead of leaving the adapter idle until restarted by hand.
|
|
149
|
+
- Changed: recurring errors such as a wrong API key are logged once instead of every poll cycle, and stopping the adapter no longer leaves a red error line in the log.
|
|
150
|
+
- Changed: short ioBroker database hiccups no longer flip the connection indicator — it now reflects only the parcel.app connection.
|
|
151
|
+
- Changed: the fallback package name ("Package …") is localized like all other texts, and the adapter is listed under a fitting admin category (misc-data).
|
|
152
|
+
- Changed: the automatic poll after adding a delivery now respects the one-minute pacing, so bulk-adds can no longer exhaust the hourly API budget.
|
|
153
|
+
|
|
154
|
+
### 0.9.0 (2026-06-23) — stable
|
|
155
|
+
|
|
156
|
+
- Fixed: tracked packages could disappear from the object tree after a temporary update error or an unexpected API response — a package is now kept until parcel.app actually stops returning it.
|
|
157
|
+
- Changed: multi-day delivery windows now show the date on each side (e.g. `12-06 14:30 - 12-08 18:30`) instead of looking same-day; out-of-range or reversed dates no longer produce a misleading window.
|
|
158
|
+
|
|
132
159
|
### 0.8.0 (2026-06-19)
|
|
133
160
|
|
|
134
161
|
- The delivery window is now also shown for carriers that report it only as a date/time range, not just when the API provides a Unix timestamp.
|
|
135
162
|
- When adding a delivery via script, you can now set an optional tracking language and request a push confirmation.
|
|
136
163
|
|
|
137
|
-
### 0.7.2 (2026-06-12)
|
|
164
|
+
### 0.7.2 (2026-06-12) — stable
|
|
138
165
|
|
|
139
166
|
- Much quieter state updates: a package's last-updated timestamp now only changes when its tracking data actually changed, and device entries are no longer rewritten on every poll
|
|
140
167
|
- Adding a delivery with a malformed request now returns a clear error message instead of failing cryptically
|
|
@@ -143,16 +170,6 @@ sendTo("parcelapp.0", "addDelivery", {
|
|
|
143
170
|
|
|
144
171
|
- Fixed a timezone edge case in delivery estimates: when the API reports only a calendar date, the estimate could be off by a day in time zones west of UTC — now stable everywhere.
|
|
145
172
|
|
|
146
|
-
### 0.7.0 (2026-06-07)
|
|
147
|
-
|
|
148
|
-
- Added optional Sentry error reporting: crashes are sent to the developer so issues get fixed faster. Active only with ioBroker diagnostics enabled; anonymous.
|
|
149
|
-
|
|
150
|
-
### 0.6.0 (2026-05-31)
|
|
151
|
-
|
|
152
|
-
- The summary delivery window now covers the full time range when several packages are expected the same day — previously an overlapping window could be cut short.
|
|
153
|
-
- Packages reported with an unrecognized status are no longer mistaken for delivered and removed; they stay visible as "Unknown".
|
|
154
|
-
- A delivery added via the admin button now appears immediately instead of only after the next polling cycle.
|
|
155
|
-
|
|
156
173
|
[Older changelogs can be found there](CHANGELOG_OLD.md)
|
|
157
174
|
|
|
158
175
|
## Support
|
package/admin/i18n/de.json
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
"apiKeyInfo": "Gib deinen parcel.app API-Schlüssel ein. Ein Premium-Abo wird benötigt. Den Schlüssel findest du unter web.parcelapp.net → API-Bereich.",
|
|
4
4
|
"label_apiKey": "API-Schlüssel",
|
|
5
5
|
"btn_checkConnection": "Verbindung testen",
|
|
6
|
-
"msg_connectionOk": "Verbindung erfolgreich!",
|
|
7
|
-
"msg_connectionFailed": "Verbindung fehlgeschlagen!",
|
|
8
6
|
"header_polling": "Abfrage",
|
|
9
7
|
"label_pollInterval": "Abfrageintervall (Minuten)",
|
|
10
8
|
"tooltip_pollInterval": "Wie oft Lieferupdates abgefragt werden (5-60 Minuten, Standard: 10). Rate-Limit: 20 Anfragen/Stunde.",
|
|
@@ -36,5 +34,15 @@
|
|
|
36
34
|
"estimateOverdue": "überfällig",
|
|
37
35
|
"estimateToday": "heute",
|
|
38
36
|
"estimateTomorrow": "morgen",
|
|
39
|
-
"estimateDays": "in %
|
|
37
|
+
"estimateDays": "in %s Tagen",
|
|
38
|
+
"status_0": "Zugestellt",
|
|
39
|
+
"status_1": "Eingefroren",
|
|
40
|
+
"status_2": "Unterwegs",
|
|
41
|
+
"status_3": "Abholung erwartet",
|
|
42
|
+
"status_4": "In Zustellung",
|
|
43
|
+
"status_5": "Nicht gefunden",
|
|
44
|
+
"status_6": "Zustellversuch gescheitert",
|
|
45
|
+
"status_7": "Ausnahme",
|
|
46
|
+
"status_8": "Registriert",
|
|
47
|
+
"packageName": "Paket %s"
|
|
40
48
|
}
|
package/admin/i18n/en.json
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
"apiKeyInfo": "Enter your parcel.app API key. A Premium subscription is required. Get your key at web.parcelapp.net → API panel.",
|
|
4
4
|
"label_apiKey": "API Key",
|
|
5
5
|
"btn_checkConnection": "Test Connection",
|
|
6
|
-
"msg_connectionOk": "Connection successful!",
|
|
7
|
-
"msg_connectionFailed": "Connection failed!",
|
|
8
6
|
"header_polling": "Polling",
|
|
9
7
|
"label_pollInterval": "Poll Interval (minutes)",
|
|
10
8
|
"tooltip_pollInterval": "How often to fetch delivery updates (5-60 minutes, default: 10). Rate limit: 20 requests/hour.",
|
|
@@ -36,5 +34,15 @@
|
|
|
36
34
|
"estimateOverdue": "overdue",
|
|
37
35
|
"estimateToday": "today",
|
|
38
36
|
"estimateTomorrow": "tomorrow",
|
|
39
|
-
"estimateDays": "in %
|
|
37
|
+
"estimateDays": "in %s days",
|
|
38
|
+
"status_0": "Delivered",
|
|
39
|
+
"status_1": "Frozen",
|
|
40
|
+
"status_2": "In Transit",
|
|
41
|
+
"status_3": "Awaiting Pickup",
|
|
42
|
+
"status_4": "Out for Delivery",
|
|
43
|
+
"status_5": "Not Found",
|
|
44
|
+
"status_6": "Delivery Attempt Failed",
|
|
45
|
+
"status_7": "Exception",
|
|
46
|
+
"status_8": "Info Received",
|
|
47
|
+
"packageName": "Package %s"
|
|
40
48
|
}
|
package/admin/i18n/es.json
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
"apiKeyInfo": "Introduce tu clave API de parcel.app. Se requiere una suscripción Premium. Obtén tu clave en web.parcelapp.net → panel API.",
|
|
4
4
|
"label_apiKey": "Clave API",
|
|
5
5
|
"btn_checkConnection": "Probar conexión",
|
|
6
|
-
"msg_connectionOk": "¡Conexión exitosa!",
|
|
7
|
-
"msg_connectionFailed": "¡Error de conexión!",
|
|
8
6
|
"header_polling": "Consulta",
|
|
9
7
|
"label_pollInterval": "Intervalo de consulta (minutos)",
|
|
10
8
|
"tooltip_pollInterval": "Con qué frecuencia obtener actualizaciones de entrega (5-60 minutos, predeterminado: 10). Límite: 20 solicitudes/hora.",
|
|
@@ -36,5 +34,15 @@
|
|
|
36
34
|
"estimateOverdue": "atrasado",
|
|
37
35
|
"estimateToday": "hoy",
|
|
38
36
|
"estimateTomorrow": "mañana",
|
|
39
|
-
"estimateDays": "en %
|
|
37
|
+
"estimateDays": "en %s días",
|
|
38
|
+
"status_0": "Entregado",
|
|
39
|
+
"status_1": "Congelado",
|
|
40
|
+
"status_2": "En tránsito",
|
|
41
|
+
"status_3": "Esperando recogida",
|
|
42
|
+
"status_4": "En reparto",
|
|
43
|
+
"status_5": "No encontrado",
|
|
44
|
+
"status_6": "Intento de entrega fallido",
|
|
45
|
+
"status_7": "Excepción",
|
|
46
|
+
"status_8": "Registrado",
|
|
47
|
+
"packageName": "Paquete %s"
|
|
40
48
|
}
|
package/admin/i18n/fr.json
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
"apiKeyInfo": "Entrez votre clé API parcel.app. Un abonnement Premium est requis. Obtenez votre clé sur web.parcelapp.net → panneau API.",
|
|
4
4
|
"label_apiKey": "Clé API",
|
|
5
5
|
"btn_checkConnection": "Tester la connexion",
|
|
6
|
-
"msg_connectionOk": "Connexion réussie !",
|
|
7
|
-
"msg_connectionFailed": "Échec de la connexion !",
|
|
8
6
|
"header_polling": "Interrogation",
|
|
9
7
|
"label_pollInterval": "Intervalle d interrogation (minutes)",
|
|
10
8
|
"tooltip_pollInterval": "Fréquence de récupération des mises à jour de livraison (5-60 minutes, défaut : 10). Limite : 20 requêtes/heure.",
|
|
@@ -36,5 +34,15 @@
|
|
|
36
34
|
"estimateOverdue": "en retard",
|
|
37
35
|
"estimateToday": "aujourd'hui",
|
|
38
36
|
"estimateTomorrow": "demain",
|
|
39
|
-
"estimateDays": "dans %
|
|
37
|
+
"estimateDays": "dans %s jours",
|
|
38
|
+
"status_0": "Livré",
|
|
39
|
+
"status_1": "Gelé",
|
|
40
|
+
"status_2": "En transit",
|
|
41
|
+
"status_3": "En attente de retrait",
|
|
42
|
+
"status_4": "En cours de livraison",
|
|
43
|
+
"status_5": "Introuvable",
|
|
44
|
+
"status_6": "Échec de la livraison",
|
|
45
|
+
"status_7": "Exception",
|
|
46
|
+
"status_8": "Enregistré",
|
|
47
|
+
"packageName": "Colis %s"
|
|
40
48
|
}
|
package/admin/i18n/it.json
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
"apiKeyInfo": "Inserisci la tua chiave API parcel.app. È necessario un abbonamento Premium. Ottieni la tua chiave su web.parcelapp.net → pannello API.",
|
|
4
4
|
"label_apiKey": "Chiave API",
|
|
5
5
|
"btn_checkConnection": "Testa connessione",
|
|
6
|
-
"msg_connectionOk": "Connessione riuscita!",
|
|
7
|
-
"msg_connectionFailed": "Connessione fallita!",
|
|
8
6
|
"header_polling": "Polling",
|
|
9
7
|
"label_pollInterval": "Intervallo di polling (minuti)",
|
|
10
8
|
"tooltip_pollInterval": "Frequenza di aggiornamento delle consegne (5-60 minuti, predefinito: 10). Limite: 20 richieste/ora.",
|
|
@@ -36,5 +34,15 @@
|
|
|
36
34
|
"estimateOverdue": "in ritardo",
|
|
37
35
|
"estimateToday": "oggi",
|
|
38
36
|
"estimateTomorrow": "domani",
|
|
39
|
-
"estimateDays": "tra %
|
|
37
|
+
"estimateDays": "tra %s giorni",
|
|
38
|
+
"status_0": "Consegnato",
|
|
39
|
+
"status_1": "Congelato",
|
|
40
|
+
"status_2": "In transito",
|
|
41
|
+
"status_3": "In attesa di ritiro",
|
|
42
|
+
"status_4": "In consegna",
|
|
43
|
+
"status_5": "Non trovato",
|
|
44
|
+
"status_6": "Consegna fallita",
|
|
45
|
+
"status_7": "Eccezione",
|
|
46
|
+
"status_8": "Registrato",
|
|
47
|
+
"packageName": "Pacco %s"
|
|
40
48
|
}
|
package/admin/i18n/nl.json
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
"apiKeyInfo": "Voer je parcel.app API-sleutel in. Een Premium-abonnement is vereist. Haal je sleutel op via web.parcelapp.net → API-paneel.",
|
|
4
4
|
"label_apiKey": "API-sleutel",
|
|
5
5
|
"btn_checkConnection": "Verbinding testen",
|
|
6
|
-
"msg_connectionOk": "Verbinding succesvol!",
|
|
7
|
-
"msg_connectionFailed": "Verbinding mislukt!",
|
|
8
6
|
"header_polling": "Polling",
|
|
9
7
|
"label_pollInterval": "Polling-interval (minuten)",
|
|
10
8
|
"tooltip_pollInterval": "Hoe vaak bezorgingsupdates ophalen (5-60 minuten, standaard: 10). Limiet: 20 verzoeken/uur.",
|
|
@@ -36,5 +34,15 @@
|
|
|
36
34
|
"estimateOverdue": "te laat",
|
|
37
35
|
"estimateToday": "vandaag",
|
|
38
36
|
"estimateTomorrow": "morgen",
|
|
39
|
-
"estimateDays": "over %
|
|
37
|
+
"estimateDays": "over %s dagen",
|
|
38
|
+
"status_0": "Bezorgd",
|
|
39
|
+
"status_1": "Bevroren",
|
|
40
|
+
"status_2": "Onderweg",
|
|
41
|
+
"status_3": "Wacht op ophaling",
|
|
42
|
+
"status_4": "Wordt bezorgd",
|
|
43
|
+
"status_5": "Niet gevonden",
|
|
44
|
+
"status_6": "Bezorgpoging mislukt",
|
|
45
|
+
"status_7": "Uitzondering",
|
|
46
|
+
"status_8": "Geregistreerd",
|
|
47
|
+
"packageName": "Pakket %s"
|
|
40
48
|
}
|
package/admin/i18n/pl.json
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
"apiKeyInfo": "Wprowadź klucz API parcel.app. Wymagana subskrypcja Premium. Uzyskaj klucz na web.parcelapp.net → panel API.",
|
|
4
4
|
"label_apiKey": "Klucz API",
|
|
5
5
|
"btn_checkConnection": "Testuj połączenie",
|
|
6
|
-
"msg_connectionOk": "Połączenie udane!",
|
|
7
|
-
"msg_connectionFailed": "Połączenie nieudane!",
|
|
8
6
|
"header_polling": "Odpytywanie",
|
|
9
7
|
"label_pollInterval": "Interwał odpytywania (minuty)",
|
|
10
8
|
"tooltip_pollInterval": "Jak często pobierać aktualizacje dostaw (5-60 minut, domyślnie: 10). Limit: 20 zapytań/godzinę.",
|
|
@@ -36,5 +34,15 @@
|
|
|
36
34
|
"estimateOverdue": "zaległe",
|
|
37
35
|
"estimateToday": "dzisiaj",
|
|
38
36
|
"estimateTomorrow": "jutro",
|
|
39
|
-
"estimateDays": "za %
|
|
37
|
+
"estimateDays": "za %s dni",
|
|
38
|
+
"status_0": "Dostarczone",
|
|
39
|
+
"status_1": "Zamrożone",
|
|
40
|
+
"status_2": "W drodze",
|
|
41
|
+
"status_3": "Oczekuje na odbiór",
|
|
42
|
+
"status_4": "W doręczeniu",
|
|
43
|
+
"status_5": "Nie znaleziono",
|
|
44
|
+
"status_6": "Nieudana próba doręczenia",
|
|
45
|
+
"status_7": "Wyjątek",
|
|
46
|
+
"status_8": "Zarejestrowane",
|
|
47
|
+
"packageName": "Paczka %s"
|
|
40
48
|
}
|
package/admin/i18n/pt.json
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
"apiKeyInfo": "Insira sua chave API do parcel.app. É necessária uma assinatura Premium. Obtenha sua chave em web.parcelapp.net → painel API.",
|
|
4
4
|
"label_apiKey": "Chave API",
|
|
5
5
|
"btn_checkConnection": "Testar Conexão",
|
|
6
|
-
"msg_connectionOk": "Conexão bem-sucedida!",
|
|
7
|
-
"msg_connectionFailed": "Falha na conexão!",
|
|
8
6
|
"header_polling": "Consulta",
|
|
9
7
|
"label_pollInterval": "Intervalo de consulta (minutos)",
|
|
10
8
|
"tooltip_pollInterval": "Com que frequência buscar atualizações de entrega (5-60 minutos, padrão: 10). Limite: 20 solicitações/hora.",
|
|
@@ -36,5 +34,15 @@
|
|
|
36
34
|
"estimateOverdue": "atrasado",
|
|
37
35
|
"estimateToday": "hoje",
|
|
38
36
|
"estimateTomorrow": "amanhã",
|
|
39
|
-
"estimateDays": "em %
|
|
37
|
+
"estimateDays": "em %s dias",
|
|
38
|
+
"status_0": "Entregue",
|
|
39
|
+
"status_1": "Congelado",
|
|
40
|
+
"status_2": "Em trânsito",
|
|
41
|
+
"status_3": "Aguardando recolha",
|
|
42
|
+
"status_4": "Em entrega",
|
|
43
|
+
"status_5": "Não encontrado",
|
|
44
|
+
"status_6": "Tentativa de entrega falhou",
|
|
45
|
+
"status_7": "Exceção",
|
|
46
|
+
"status_8": "Registado",
|
|
47
|
+
"packageName": "Encomenda %s"
|
|
40
48
|
}
|
package/admin/i18n/ru.json
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
"apiKeyInfo": "Введите API-ключ parcel.app. Требуется Premium-подписка. Получите ключ на web.parcelapp.net → раздел API.",
|
|
4
4
|
"label_apiKey": "API-ключ",
|
|
5
5
|
"btn_checkConnection": "Проверить соединение",
|
|
6
|
-
"msg_connectionOk": "Соединение успешно!",
|
|
7
|
-
"msg_connectionFailed": "Ошибка соединения!",
|
|
8
6
|
"header_polling": "Опрос",
|
|
9
7
|
"label_pollInterval": "Интервал опроса (минуты)",
|
|
10
8
|
"tooltip_pollInterval": "Как часто получать обновления доставки (5-60 минут, по умолчанию: 10). Лимит: 20 запросов/час.",
|
|
@@ -36,5 +34,15 @@
|
|
|
36
34
|
"estimateOverdue": "просрочено",
|
|
37
35
|
"estimateToday": "сегодня",
|
|
38
36
|
"estimateTomorrow": "завтра",
|
|
39
|
-
"estimateDays": "через %
|
|
37
|
+
"estimateDays": "через %s дн.",
|
|
38
|
+
"status_0": "Доставлено",
|
|
39
|
+
"status_1": "Заморожено",
|
|
40
|
+
"status_2": "В пути",
|
|
41
|
+
"status_3": "Ожидает получения",
|
|
42
|
+
"status_4": "Доставляется",
|
|
43
|
+
"status_5": "Не найдено",
|
|
44
|
+
"status_6": "Неудачная доставка",
|
|
45
|
+
"status_7": "Исключение",
|
|
46
|
+
"status_8": "Зарегистрировано",
|
|
47
|
+
"packageName": "Посылка %s"
|
|
40
48
|
}
|
package/admin/i18n/uk.json
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
"apiKeyInfo": "Введіть ваш API-ключ parcel.app. Потрібна Premium-підписка. Отримайте ключ на web.parcelapp.net → панель API.",
|
|
4
4
|
"label_apiKey": "API-ключ",
|
|
5
5
|
"btn_checkConnection": "Перевірити з'єднання",
|
|
6
|
-
"msg_connectionOk": "З'єднання успішне!",
|
|
7
|
-
"msg_connectionFailed": "Помилка з'єднання!",
|
|
8
6
|
"header_polling": "Опитування",
|
|
9
7
|
"label_pollInterval": "Інтервал опитування (хвилини)",
|
|
10
8
|
"tooltip_pollInterval": "Як часто отримувати оновлення доставки (5-60 хвилин, за замовчуванням: 10). Ліміт: 20 запитів/годину.",
|
|
@@ -36,5 +34,15 @@
|
|
|
36
34
|
"estimateOverdue": "прострочено",
|
|
37
35
|
"estimateToday": "сьогодні",
|
|
38
36
|
"estimateTomorrow": "завтра",
|
|
39
|
-
"estimateDays": "через %
|
|
37
|
+
"estimateDays": "через %s дн.",
|
|
38
|
+
"status_0": "Доставлено",
|
|
39
|
+
"status_1": "Заморожено",
|
|
40
|
+
"status_2": "В дорозі",
|
|
41
|
+
"status_3": "Очікує отримання",
|
|
42
|
+
"status_4": "Доставляється",
|
|
43
|
+
"status_5": "Не знайдено",
|
|
44
|
+
"status_6": "Невдала спроба доставки",
|
|
45
|
+
"status_7": "Виняток",
|
|
46
|
+
"status_8": "Зареєстровано",
|
|
47
|
+
"packageName": "Посилка %s"
|
|
40
48
|
}
|
package/admin/i18n/zh-cn.json
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
"apiKeyInfo": "输入你的 parcel.app API 密钥。需要 Premium 订阅。在 web.parcelapp.net → API 面板获取密钥。",
|
|
4
4
|
"label_apiKey": "API 密钥",
|
|
5
5
|
"btn_checkConnection": "测试连接",
|
|
6
|
-
"msg_connectionOk": "连接成功!",
|
|
7
|
-
"msg_connectionFailed": "连接失败!",
|
|
8
6
|
"header_polling": "轮询",
|
|
9
7
|
"label_pollInterval": "轮询间隔(分钟)",
|
|
10
8
|
"tooltip_pollInterval": "多久获取一次快递更新(5-60分钟,默认:10)。速率限制:20次请求/小时。",
|
|
@@ -36,5 +34,15 @@
|
|
|
36
34
|
"estimateOverdue": "已逾期",
|
|
37
35
|
"estimateToday": "今天",
|
|
38
36
|
"estimateTomorrow": "明天",
|
|
39
|
-
"estimateDays": "%
|
|
37
|
+
"estimateDays": "%s 天后",
|
|
38
|
+
"status_0": "已送达",
|
|
39
|
+
"status_1": "已冻结",
|
|
40
|
+
"status_2": "运输中",
|
|
41
|
+
"status_3": "等待取件",
|
|
42
|
+
"status_4": "派送中",
|
|
43
|
+
"status_5": "未找到",
|
|
44
|
+
"status_6": "派送失败",
|
|
45
|
+
"status_7": "异常",
|
|
46
|
+
"status_8": "已登记",
|
|
47
|
+
"packageName": "包裹 %s"
|
|
40
48
|
}
|
package/admin/jsonConfig.json
CHANGED
package/build/lib/coerce.js
CHANGED
|
@@ -21,7 +21,8 @@ __export(coerce_exports, {
|
|
|
21
21
|
coerceClampedInt: () => coerceClampedInt,
|
|
22
22
|
coerceFiniteNumber: () => coerceFiniteNumber,
|
|
23
23
|
errText: () => errText,
|
|
24
|
-
isTrueish: () => isTrueish
|
|
24
|
+
isTrueish: () => isTrueish,
|
|
25
|
+
oneLine: () => oneLine
|
|
25
26
|
});
|
|
26
27
|
module.exports = __toCommonJS(coerce_exports);
|
|
27
28
|
const DECIMAL_NUMBER_RE = /^-?\d+(\.\d+)?$/;
|
|
@@ -77,11 +78,15 @@ function coerceClampedInt(raw, min, max, defaultValue) {
|
|
|
77
78
|
}
|
|
78
79
|
return Math.max(min, Math.min(max, Math.floor(n)));
|
|
79
80
|
}
|
|
81
|
+
function oneLine(value) {
|
|
82
|
+
return value.replace(/[\r\n\t\0\v\f\u2028\u2029]+/g, " ");
|
|
83
|
+
}
|
|
80
84
|
// Annotate the CommonJS export names for ESM import in node:
|
|
81
85
|
0 && (module.exports = {
|
|
82
86
|
coerceClampedInt,
|
|
83
87
|
coerceFiniteNumber,
|
|
84
88
|
errText,
|
|
85
|
-
isTrueish
|
|
89
|
+
isTrueish,
|
|
90
|
+
oneLine
|
|
86
91
|
});
|
|
87
92
|
//# sourceMappingURL=coerce.js.map
|
package/build/lib/coerce.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/coerce.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Boundary coercion helpers for external API data.\n *\n * The parcel.app API is documented but field types still drift in practice\n * (rare success-flag returned as `\"true\"` string, occasional null where a\n * number is expected). These helpers guard against NaN/Infinity/non-string\n * values reaching ioBroker states.\n */\n\n// Strict decimal regex \u2014 only optional minus sign + digits + optional fractional part.\n// Rejects HEX (`0x...`), exponential (`1e3`), Infinity, NaN, leading/trailing whitespace.\n// Hassemu (E8 in v1.9.0) hardened the same coerce-helper this way; homewizard\n// adopted it in v0.7.2 (D8). Consistent with both adapters.\nconst DECIMAL_NUMBER_RE = /^-?\\d+(\\.\\d+)?$/;\n\n/**\n * Coerce to a finite number or null.\n * Accepts numbers directly; parses strict decimal strings; rejects NaN, Infinity,\n * HEX (`0x...`) and exponential notation (`1e3`).\n *\n * @param value Unknown external value\n */\nexport function coerceFiniteNumber(value: unknown): number | null {\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? value : null;\n }\n if (typeof value === \"string\" && DECIMAL_NUMBER_RE.test(value)) {\n const n = Number(value);\n return Number.isFinite(n) ? n : null;\n }\n return null;\n}\n\n/**\n * Coerce a parcel.app `success` flag. The API returns a real boolean in normal\n * operation, but the guard accepts common string/number encodings (`1`, `\"true\"`,\n * `\"1\"`) so a one-off drift doesn't break the entire poll cycle.\n *\n * @param v Value to interpret as a success flag\n */\nexport function isTrueish(v: unknown): boolean {\n if (typeof v === \"boolean\") {\n return v;\n }\n if (typeof v === \"number\") {\n return v === 1;\n }\n if (typeof v === \"string\") {\n const s = v.toLowerCase();\n return s === \"true\" || s === \"1\";\n }\n return false;\n}\n\n/**\n * Extract a log-friendly message from a thrown / rejected value. Centralizes the\n * `err instanceof Error ? err.message : String(err)` pattern that otherwise\n * gets repeated at every catch-site. Plain objects are JSON-stringified so a\n * `[object Object]` log is avoided when callers throw bag-of-fields.\n *\n * @param err Caught value of unknown shape (Error, string, undefined, ...).\n */\nexport function errText(err: unknown): string {\n if (err instanceof Error) {\n return err.message;\n }\n if (err === null) {\n return \"null\";\n }\n if (err === undefined) {\n return \"undefined\";\n }\n if (typeof err === \"string\") {\n return err;\n }\n if (typeof err === \"number\" || typeof err === \"boolean\" || typeof err === \"bigint\") {\n return String(err);\n }\n // Plain objects + symbols would otherwise stringify to \"[object Object]\" / fail.\n // Prefer JSON for the common case so the log is at least diagnosable.\n try {\n return JSON.stringify(err);\n } catch {\n return Object.prototype.toString.call(err);\n }\n}\n\n/**\n * v0.4.2 (X5): coerce an admin-config integer setting (number-or-string)\n * to a finite, clamped integer. Returns `defaultValue` for non-finite\n * input \u2014 guards against `setInterval(fn, NaN)` tight-loops when the\n * config field happens to come back as a string from the admin UI.\n *\n * @param raw Raw value from `this.config.<field>`.\n * @param min Inclusive lower bound.\n * @param max Inclusive upper bound.\n * @param defaultValue Fallback when raw is missing or unparseable.\n */\nexport function coerceClampedInt(raw: unknown, min: number, max: number, defaultValue: number): number {\n const n = typeof raw === \"number\" ? raw : typeof raw === \"string\" ? parseFloat(raw) : NaN;\n if (!Number.isFinite(n)) {\n return defaultValue;\n }\n return Math.max(min, Math.min(max, Math.floor(n)));\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA,MAAM,oBAAoB;AASnB,SAAS,mBAAmB,OAA+B;AAChE,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AAAA,EAC1C;AACA,MAAI,OAAO,UAAU,YAAY,kBAAkB,KAAK,KAAK,GAAG;AAC9D,UAAM,IAAI,OAAO,KAAK;AACtB,WAAO,OAAO,SAAS,CAAC,IAAI,IAAI;AAAA,EAClC;AACA,SAAO;AACT;AASO,SAAS,UAAU,GAAqB;AAC7C,MAAI,OAAO,MAAM,WAAW;AAC1B,WAAO;AAAA,EACT;AACA,MAAI,OAAO,MAAM,UAAU;AACzB,WAAO,MAAM;AAAA,EACf;AACA,MAAI,OAAO,MAAM,UAAU;AACzB,UAAM,IAAI,EAAE,YAAY;AACxB,WAAO,MAAM,UAAU,MAAM;AAAA,EAC/B;AACA,SAAO;AACT;AAUO,SAAS,QAAQ,KAAsB;AAC5C,MAAI,eAAe,OAAO;AACxB,WAAO,IAAI;AAAA,EACb;AACA,MAAI,QAAQ,MAAM;AAChB,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,QAAW;AACrB,WAAO;AAAA,EACT;AACA,MAAI,OAAO,QAAQ,UAAU;AAC3B,WAAO;AAAA,EACT;AACA,MAAI,OAAO,QAAQ,YAAY,OAAO,QAAQ,aAAa,OAAO,QAAQ,UAAU;AAClF,WAAO,OAAO,GAAG;AAAA,EACnB;AAGA,MAAI;AACF,WAAO,KAAK,UAAU,GAAG;AAAA,EAC3B,QAAQ;AACN,WAAO,OAAO,UAAU,SAAS,KAAK,GAAG;AAAA,EAC3C;AACF;AAaO,SAAS,iBAAiB,KAAc,KAAa,KAAa,cAA8B;AACrG,QAAM,IAAI,OAAO,QAAQ,WAAW,MAAM,OAAO,QAAQ,WAAW,WAAW,GAAG,IAAI;AACtF,MAAI,CAAC,OAAO,SAAS,CAAC,GAAG;AACvB,WAAO;AAAA,EACT;AACA,SAAO,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC;AACnD;",
|
|
4
|
+
"sourcesContent": ["/**\n * Boundary coercion helpers for external API data.\n *\n * The parcel.app API is documented but field types still drift in practice\n * (rare success-flag returned as `\"true\"` string, occasional null where a\n * number is expected). These helpers guard against NaN/Infinity/non-string\n * values reaching ioBroker states.\n */\n\n// Strict decimal regex \u2014 only optional minus sign + digits + optional fractional part.\n// Rejects HEX (`0x...`), exponential (`1e3`), Infinity, NaN, leading/trailing whitespace.\n// Hassemu (E8 in v1.9.0) hardened the same coerce-helper this way; homewizard\n// adopted it in v0.7.2 (D8). Consistent with both adapters.\nconst DECIMAL_NUMBER_RE = /^-?\\d+(\\.\\d+)?$/;\n\n/**\n * Coerce to a finite number or null.\n * Accepts numbers directly; parses strict decimal strings; rejects NaN, Infinity,\n * HEX (`0x...`) and exponential notation (`1e3`).\n *\n * @param value Unknown external value\n */\nexport function coerceFiniteNumber(value: unknown): number | null {\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? value : null;\n }\n if (typeof value === \"string\" && DECIMAL_NUMBER_RE.test(value)) {\n const n = Number(value);\n return Number.isFinite(n) ? n : null;\n }\n return null;\n}\n\n/**\n * Coerce a parcel.app `success` flag. The API returns a real boolean in normal\n * operation, but the guard accepts common string/number encodings (`1`, `\"true\"`,\n * `\"1\"`) so a one-off drift doesn't break the entire poll cycle.\n *\n * @param v Value to interpret as a success flag\n */\nexport function isTrueish(v: unknown): boolean {\n if (typeof v === \"boolean\") {\n return v;\n }\n if (typeof v === \"number\") {\n return v === 1;\n }\n if (typeof v === \"string\") {\n const s = v.toLowerCase();\n return s === \"true\" || s === \"1\";\n }\n return false;\n}\n\n/**\n * Extract a log-friendly message from a thrown / rejected value. Centralizes the\n * `err instanceof Error ? err.message : String(err)` pattern that otherwise\n * gets repeated at every catch-site. Plain objects are JSON-stringified so a\n * `[object Object]` log is avoided when callers throw bag-of-fields.\n *\n * @param err Caught value of unknown shape (Error, string, undefined, ...).\n */\nexport function errText(err: unknown): string {\n if (err instanceof Error) {\n return err.message;\n }\n if (err === null) {\n return \"null\";\n }\n if (err === undefined) {\n return \"undefined\";\n }\n if (typeof err === \"string\") {\n return err;\n }\n if (typeof err === \"number\" || typeof err === \"boolean\" || typeof err === \"bigint\") {\n return String(err);\n }\n // Plain objects + symbols would otherwise stringify to \"[object Object]\" / fail.\n // Prefer JSON for the common case so the log is at least diagnosable.\n try {\n return JSON.stringify(err);\n } catch {\n return Object.prototype.toString.call(err);\n }\n}\n\n/**\n * v0.4.2 (X5): coerce an admin-config integer setting (number-or-string)\n * to a finite, clamped integer. Returns `defaultValue` for non-finite\n * input \u2014 guards against `setInterval(fn, NaN)` tight-loops when the\n * config field happens to come back as a string from the admin UI.\n *\n * @param raw Raw value from `this.config.<field>`.\n * @param min Inclusive lower bound.\n * @param max Inclusive upper bound.\n * @param defaultValue Fallback when raw is missing or unparseable.\n */\nexport function coerceClampedInt(raw: unknown, min: number, max: number, defaultValue: number): number {\n const n = typeof raw === \"number\" ? raw : typeof raw === \"string\" ? parseFloat(raw) : NaN;\n if (!Number.isFinite(n)) {\n return defaultValue;\n }\n return Math.max(min, Math.min(max, Math.floor(n)));\n}\n\n/**\n * Collapse control-character runs (CR / LF / TAB / NUL / VT / FF and the\n * Unicode line separators U+2028/U+2029) in an untrusted string to a single\n * space before it is interpolated into a log line \u2014 prevents log-injection\n * (a forged second log line) from external values (tracking number, carrier\n * code, raw API body, collision raw-key with its NUL separator, \u2026). Fleet\n * convention (hassemu/hueemu v1.36.0 S4); widened in v0.10.0 (I10).\n *\n * @param value Untrusted string to flatten for single-line logging.\n */\nexport function oneLine(value: string): string {\n return value.replace(/[\\r\\n\\t\\0\\v\\f\\u2028\\u2029]+/g, \" \");\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA,MAAM,oBAAoB;AASnB,SAAS,mBAAmB,OAA+B;AAChE,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AAAA,EAC1C;AACA,MAAI,OAAO,UAAU,YAAY,kBAAkB,KAAK,KAAK,GAAG;AAC9D,UAAM,IAAI,OAAO,KAAK;AACtB,WAAO,OAAO,SAAS,CAAC,IAAI,IAAI;AAAA,EAClC;AACA,SAAO;AACT;AASO,SAAS,UAAU,GAAqB;AAC7C,MAAI,OAAO,MAAM,WAAW;AAC1B,WAAO;AAAA,EACT;AACA,MAAI,OAAO,MAAM,UAAU;AACzB,WAAO,MAAM;AAAA,EACf;AACA,MAAI,OAAO,MAAM,UAAU;AACzB,UAAM,IAAI,EAAE,YAAY;AACxB,WAAO,MAAM,UAAU,MAAM;AAAA,EAC/B;AACA,SAAO;AACT;AAUO,SAAS,QAAQ,KAAsB;AAC5C,MAAI,eAAe,OAAO;AACxB,WAAO,IAAI;AAAA,EACb;AACA,MAAI,QAAQ,MAAM;AAChB,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,QAAW;AACrB,WAAO;AAAA,EACT;AACA,MAAI,OAAO,QAAQ,UAAU;AAC3B,WAAO;AAAA,EACT;AACA,MAAI,OAAO,QAAQ,YAAY,OAAO,QAAQ,aAAa,OAAO,QAAQ,UAAU;AAClF,WAAO,OAAO,GAAG;AAAA,EACnB;AAGA,MAAI;AACF,WAAO,KAAK,UAAU,GAAG;AAAA,EAC3B,QAAQ;AACN,WAAO,OAAO,UAAU,SAAS,KAAK,GAAG;AAAA,EAC3C;AACF;AAaO,SAAS,iBAAiB,KAAc,KAAa,KAAa,cAA8B;AACrG,QAAM,IAAI,OAAO,QAAQ,WAAW,MAAM,OAAO,QAAQ,WAAW,WAAW,GAAG,IAAI;AACtF,MAAI,CAAC,OAAO,SAAS,CAAC,GAAG;AACvB,WAAO;AAAA,EACT;AACA,SAAO,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC;AACnD;AAYO,SAAS,QAAQ,OAAuB;AAC7C,SAAO,MAAM,QAAQ,gCAAgC,GAAG;AAC1D;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/build/lib/i18n.js
CHANGED
|
@@ -18,15 +18,42 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var i18n_exports = {};
|
|
20
20
|
__export(i18n_exports, {
|
|
21
|
-
|
|
21
|
+
packageName: () => packageName,
|
|
22
|
+
statusLabel: () => statusLabel,
|
|
23
|
+
tName: () => tName,
|
|
24
|
+
tText: () => tText
|
|
22
25
|
});
|
|
23
26
|
module.exports = __toCommonJS(i18n_exports);
|
|
24
27
|
var import_adapter_core = require("@iobroker/adapter-core");
|
|
25
28
|
function tName(key) {
|
|
26
29
|
return import_adapter_core.I18n.getTranslatedObject(key);
|
|
27
30
|
}
|
|
31
|
+
function tText(key, ...args) {
|
|
32
|
+
return import_adapter_core.I18n.translate(key, ...args);
|
|
33
|
+
}
|
|
34
|
+
const STATUS_KEYS = {
|
|
35
|
+
0: "status_0",
|
|
36
|
+
1: "status_1",
|
|
37
|
+
2: "status_2",
|
|
38
|
+
3: "status_3",
|
|
39
|
+
4: "status_4",
|
|
40
|
+
5: "status_5",
|
|
41
|
+
6: "status_6",
|
|
42
|
+
7: "status_7",
|
|
43
|
+
8: "status_8"
|
|
44
|
+
};
|
|
45
|
+
function statusLabel(code) {
|
|
46
|
+
const key = STATUS_KEYS[code];
|
|
47
|
+
return key === void 0 ? void 0 : import_adapter_core.I18n.translate(key);
|
|
48
|
+
}
|
|
49
|
+
function packageName(trackingNumber) {
|
|
50
|
+
return import_adapter_core.I18n.getTranslatedObject("packageName", trackingNumber);
|
|
51
|
+
}
|
|
28
52
|
// Annotate the CommonJS export names for ESM import in node:
|
|
29
53
|
0 && (module.exports = {
|
|
30
|
-
|
|
54
|
+
packageName,
|
|
55
|
+
statusLabel,
|
|
56
|
+
tName,
|
|
57
|
+
tText
|
|
31
58
|
});
|
|
32
59
|
//# sourceMappingURL=i18n.js.map
|
package/build/lib/i18n.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/i18n.ts"],
|
|
4
|
-
"sourcesContent": ["import { I18n } from \"@iobroker/adapter-core\";\nimport type translations from \"../../admin/i18n/en.json\";\n\ntype I18nKey = keyof typeof translations;\n\n/**\n * @param key Translation key from admin/i18n/en.json\n */\nexport function tName(key: I18nKey): ioBroker.StringOrTranslated {\n return I18n.getTranslatedObject(key);\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAAqB;AAQd,SAAS,MAAM,KAA2C;AAC/D,SAAO,yBAAK,oBAAoB,GAAG;AACrC;",
|
|
4
|
+
"sourcesContent": ["import { I18n } from \"@iobroker/adapter-core\";\nimport type translations from \"../../admin/i18n/en.json\";\n\ntype I18nKey = keyof typeof translations;\n\n/**\n * @param key Translation key from admin/i18n/en.json\n */\nexport function tName(key: I18nKey): ioBroker.StringOrTranslated {\n return I18n.getTranslatedObject(key);\n}\n\n/**\n * Type-safe wrapper around I18n.translate \u2014 a typo'd key is a compile error,\n * matching the guarantee tName already gives object names (v0.10.0, L13).\n * `%s` placeholders are filled from args, rendered in the system language.\n *\n * @param key Translation key from admin/i18n/en.json\n * @param args Values substituted for `%s` placeholders\n */\nexport function tText(key: I18nKey, ...args: (string | number | boolean | null)[]): string {\n return I18n.translate(key, ...args);\n}\n\n/** status_code \u2192 i18n key. `satisfies` pins every entry to a real key in en.json. */\nconst STATUS_KEYS = {\n 0: \"status_0\",\n 1: \"status_1\",\n 2: \"status_2\",\n 3: \"status_3\",\n 4: \"status_4\",\n 5: \"status_5\",\n 6: \"status_6\",\n 7: \"status_7\",\n 8: \"status_8\",\n} as const satisfies Record<number, I18nKey>;\n\n/**\n * Localized status label for a parsed status code, or undefined for codes the\n * table does not know (API drift) \u2014 the caller renders its own fallback.\n * Replaces the former STATUS_LABELS table in types.ts (v0.10.0, L20): one\n * translation system (admin/i18n via adapter-core I18n) instead of two.\n *\n * @param code Parsed numeric status code\n */\nexport function statusLabel(code: number): string | undefined {\n const key = (STATUS_KEYS as Partial<Record<number, I18nKey>>)[code];\n return key === undefined ? undefined : I18n.translate(key);\n}\n\n/**\n * Localized fallback device name (\"Package <tracking>\") as a translation\n * object \u2014 getTranslatedObject substitutes `%s` in every language, so the\n * one previously hard-English user-facing label is localized too (v0.10.0, L18).\n *\n * @param trackingNumber Tracking number (or package id) interpolated into the name\n */\nexport function packageName(trackingNumber: string): ioBroker.StringOrTranslated {\n return I18n.getTranslatedObject(\"packageName\", trackingNumber);\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAAqB;AAQd,SAAS,MAAM,KAA2C;AAC/D,SAAO,yBAAK,oBAAoB,GAAG;AACrC;AAUO,SAAS,MAAM,QAAiB,MAAoD;AACzF,SAAO,yBAAK,UAAU,KAAK,GAAG,IAAI;AACpC;AAGA,MAAM,cAAc;AAAA,EAClB,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAUO,SAAS,YAAY,MAAkC;AAC5D,QAAM,MAAO,YAAiD,IAAI;AAClE,SAAO,QAAQ,SAAY,SAAY,yBAAK,UAAU,GAAG;AAC3D;AASO,SAAS,YAAY,gBAAqD;AAC/E,SAAO,yBAAK,oBAAoB,eAAe,cAAc;AAC/D;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|