iobroker.parcelapp 0.4.4 → 0.4.5
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 +3 -5
- package/build/lib/i18n-states.js +70 -0
- package/build/lib/i18n-states.js.map +2 -2
- package/build/lib/state-manager.js +26 -121
- package/build/lib/state-manager.js.map +2 -2
- package/io-package.json +15 -15
- package/package.json +11 -32
package/README.md
CHANGED
|
@@ -122,6 +122,9 @@ The delivery is added to your parcel.app account and immediately appears in ioBr
|
|
|
122
122
|
Placeholder for the next version (at the beginning of the line):
|
|
123
123
|
### **WORK IN PROGRESS**
|
|
124
124
|
-->
|
|
125
|
+
### 0.4.5 (2026-05-17)
|
|
126
|
+
- Fixed adapter icon not displaying in some admin environments (Content Security Policy).
|
|
127
|
+
|
|
125
128
|
### 0.4.4 (2026-05-13)
|
|
126
129
|
- Adapter shuts down cleanly even if the "Test Connection" button was still running — the test request is now aborted at unload along with regular polling.
|
|
127
130
|
|
|
@@ -139,11 +142,6 @@ The delivery is added to your parcel.app account and immediately appears in ioBr
|
|
|
139
142
|
|
|
140
143
|
- Adapter log messages are now English only, in line with the ioBroker community standard. Localized state names (11 languages) are unchanged.
|
|
141
144
|
|
|
142
|
-
### 0.4.0 (2026-05-06)
|
|
143
|
-
|
|
144
|
-
- State names now follow your ioBroker system language (11 languages).
|
|
145
|
-
- Minimum requirements: Node.js 22 and ioBroker Admin 7.8.23.
|
|
146
|
-
|
|
147
145
|
Older entries are in [CHANGELOG_OLD.md](CHANGELOG_OLD.md).
|
|
148
146
|
|
|
149
147
|
## Support
|
package/build/lib/i18n-states.js
CHANGED
|
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var i18n_states_exports = {};
|
|
20
20
|
__export(i18n_states_exports, {
|
|
21
|
+
ESTIMATE_LABELS: () => ESTIMATE_LABELS,
|
|
21
22
|
STATE_NAMES: () => STATE_NAMES,
|
|
22
23
|
tName: () => tName
|
|
23
24
|
});
|
|
@@ -208,11 +209,80 @@ const STATE_NAMES = {
|
|
|
208
209
|
"zh-cn": "\u5408\u5E76\u6D3E\u9001\u65F6\u6BB5"
|
|
209
210
|
}
|
|
210
211
|
};
|
|
212
|
+
const ESTIMATE_LABELS = {
|
|
213
|
+
de: {
|
|
214
|
+
overdue: "\xFCberf\xE4llig",
|
|
215
|
+
today: "heute",
|
|
216
|
+
tomorrow: "morgen",
|
|
217
|
+
days: "in %d Tagen"
|
|
218
|
+
},
|
|
219
|
+
en: {
|
|
220
|
+
overdue: "overdue",
|
|
221
|
+
today: "today",
|
|
222
|
+
tomorrow: "tomorrow",
|
|
223
|
+
days: "in %d days"
|
|
224
|
+
},
|
|
225
|
+
ru: {
|
|
226
|
+
overdue: "\u043F\u0440\u043E\u0441\u0440\u043E\u0447\u0435\u043D\u043E",
|
|
227
|
+
today: "\u0441\u0435\u0433\u043E\u0434\u043D\u044F",
|
|
228
|
+
tomorrow: "\u0437\u0430\u0432\u0442\u0440\u0430",
|
|
229
|
+
days: "\u0447\u0435\u0440\u0435\u0437 %d \u0434\u043D."
|
|
230
|
+
},
|
|
231
|
+
pt: {
|
|
232
|
+
overdue: "atrasado",
|
|
233
|
+
today: "hoje",
|
|
234
|
+
tomorrow: "amanh\xE3",
|
|
235
|
+
days: "em %d dias"
|
|
236
|
+
},
|
|
237
|
+
nl: {
|
|
238
|
+
overdue: "te laat",
|
|
239
|
+
today: "vandaag",
|
|
240
|
+
tomorrow: "morgen",
|
|
241
|
+
days: "over %d dagen"
|
|
242
|
+
},
|
|
243
|
+
fr: {
|
|
244
|
+
overdue: "en retard",
|
|
245
|
+
today: "aujourd'hui",
|
|
246
|
+
tomorrow: "demain",
|
|
247
|
+
days: "dans %d jours"
|
|
248
|
+
},
|
|
249
|
+
it: {
|
|
250
|
+
overdue: "in ritardo",
|
|
251
|
+
today: "oggi",
|
|
252
|
+
tomorrow: "domani",
|
|
253
|
+
days: "tra %d giorni"
|
|
254
|
+
},
|
|
255
|
+
es: {
|
|
256
|
+
overdue: "atrasado",
|
|
257
|
+
today: "hoy",
|
|
258
|
+
tomorrow: "ma\xF1ana",
|
|
259
|
+
days: "en %d d\xEDas"
|
|
260
|
+
},
|
|
261
|
+
pl: {
|
|
262
|
+
overdue: "zaleg\u0142e",
|
|
263
|
+
today: "dzisiaj",
|
|
264
|
+
tomorrow: "jutro",
|
|
265
|
+
days: "za %d dni"
|
|
266
|
+
},
|
|
267
|
+
uk: {
|
|
268
|
+
overdue: "\u043F\u0440\u043E\u0441\u0442\u0440\u043E\u0447\u0435\u043D\u043E",
|
|
269
|
+
today: "\u0441\u044C\u043E\u0433\u043E\u0434\u043D\u0456",
|
|
270
|
+
tomorrow: "\u0437\u0430\u0432\u0442\u0440\u0430",
|
|
271
|
+
days: "\u0447\u0435\u0440\u0435\u0437 %d \u0434\u043D."
|
|
272
|
+
},
|
|
273
|
+
"zh-cn": {
|
|
274
|
+
overdue: "\u5DF2\u903E\u671F",
|
|
275
|
+
today: "\u4ECA\u5929",
|
|
276
|
+
tomorrow: "\u660E\u5929",
|
|
277
|
+
days: "%d \u5929\u540E"
|
|
278
|
+
}
|
|
279
|
+
};
|
|
211
280
|
function tName(key) {
|
|
212
281
|
return STATE_NAMES[key];
|
|
213
282
|
}
|
|
214
283
|
// Annotate the CommonJS export names for ESM import in node:
|
|
215
284
|
0 && (module.exports = {
|
|
285
|
+
ESTIMATE_LABELS,
|
|
216
286
|
STATE_NAMES,
|
|
217
287
|
tName
|
|
218
288
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/i18n-states.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Localized state names for parcel deliveries in 11 ioBroker system languages.\n *\n * ioBroker accepts plain strings or `{ en, de, ... }` translation objects for\n * `common.name`. Admin, vis and the Object-Browser pick the user's language\n * automatically \u2014 we just hand them the object.\n *\n * Adapter logs (`this.log.*`) stay English by ioBroker convention so that\n * user bug reports remain readable for maintainers regardless of the user's\n * system language.\n */\n\ntype Lang = \"en\" | \"de\" | \"ru\" | \"pt\" | \"nl\" | \"fr\" | \"it\" | \"es\" | \"pl\" | \"uk\" | \"zh-cn\";\n\n/** Translation object as ioBroker expects it. */\nexport type StateName = Record<Lang, string>;\n\n/** State / channel display names (`common.name`). */\nexport const STATE_NAMES: Record<string, StateName> = {\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Per-delivery states \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n carrier: {\n en: \"Carrier\",\n de: \"Versanddienst\",\n ru: \"\u041F\u0435\u0440\u0435\u0432\u043E\u0437\u0447\u0438\u043A\",\n pt: \"Transportadora\",\n nl: \"Vervoerder\",\n fr: \"Transporteur\",\n it: \"Corriere\",\n es: \"Transportista\",\n pl: \"Przewo\u017Anik\",\n uk: \"\u041F\u0435\u0440\u0435\u0432\u0456\u0437\u043D\u0438\u043A\",\n \"zh-cn\": \"\u627F\u8FD0\u5546\",\n },\n status: {\n en: \"Status\",\n de: \"Status\",\n ru: \"\u0421\u0442\u0430\u0442\u0443\u0441\",\n pt: \"Estado\",\n nl: \"Status\",\n fr: \"\u00C9tat\",\n it: \"Stato\",\n es: \"Estado\",\n pl: \"Status\",\n uk: \"\u0421\u0442\u0430\u0442\u0443\u0441\",\n \"zh-cn\": \"\u72B6\u6001\",\n },\n statusCode: {\n en: \"Status Code\",\n de: \"Status-Code\",\n ru: \"\u041A\u043E\u0434 \u0441\u0442\u0430\u0442\u0443\u0441\u0430\",\n pt: \"C\u00F3digo de estado\",\n nl: \"Statuscode\",\n fr: \"Code d'\u00E9tat\",\n it: \"Codice di stato\",\n es: \"C\u00F3digo de estado\",\n pl: \"Kod statusu\",\n uk: \"\u041A\u043E\u0434 \u0441\u0442\u0430\u0442\u0443\u0441\u0443\",\n \"zh-cn\": \"\u72B6\u6001\u4EE3\u7801\",\n },\n description: {\n en: \"Description\",\n de: \"Beschreibung\",\n ru: \"\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435\",\n pt: \"Descri\u00E7\u00E3o\",\n nl: \"Beschrijving\",\n fr: \"Description\",\n it: \"Descrizione\",\n es: \"Descripci\u00F3n\",\n pl: \"Opis\",\n uk: \"\u041E\u043F\u0438\u0441\",\n \"zh-cn\": \"\u63CF\u8FF0\",\n },\n trackingNumber: {\n en: \"Tracking Number\",\n de: \"Sendungsnummer\",\n ru: \"\u0422\u0440\u0435\u043A-\u043D\u043E\u043C\u0435\u0440\",\n pt: \"N\u00FAmero de rastreio\",\n nl: \"Trackingnummer\",\n fr: \"Num\u00E9ro de suivi\",\n it: \"Numero di tracciamento\",\n es: \"N\u00FAmero de seguimiento\",\n pl: \"Numer \u015Bledzenia\",\n uk: \"\u041D\u043E\u043C\u0435\u0440 \u0432\u0456\u0434\u0441\u0442\u0435\u0436\u0435\u043D\u043D\u044F\",\n \"zh-cn\": \"\u8FFD\u8E2A\u53F7\",\n },\n extraInfo: {\n en: \"Extra Information\",\n de: \"Zusatz-Information\",\n ru: \"\u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F\",\n pt: \"Informa\u00E7\u00E3o adicional\",\n nl: \"Extra informatie\",\n fr: \"Informations suppl\u00E9mentaires\",\n it: \"Informazioni aggiuntive\",\n es: \"Informaci\u00F3n adicional\",\n pl: \"Dodatkowe informacje\",\n uk: \"\u0414\u043E\u0434\u0430\u0442\u043A\u043E\u0432\u0430 \u0456\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0456\u044F\",\n \"zh-cn\": \"\u9644\u52A0\u4FE1\u606F\",\n },\n deliveryWindow: {\n en: \"Delivery Window\",\n de: \"Zustellfenster\",\n ru: \"\u041E\u043A\u043D\u043E \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0438\",\n pt: \"Janela de entrega\",\n nl: \"Bezorgvenster\",\n fr: \"Cr\u00E9neau de livraison\",\n it: \"Finestra di consegna\",\n es: \"Ventana de entrega\",\n pl: \"Okno dostawy\",\n uk: \"\u0412\u0456\u043A\u043D\u043E \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0438\",\n \"zh-cn\": \"\u6D3E\u9001\u65F6\u6BB5\",\n },\n deliveryEstimate: {\n en: \"Delivery Estimate\",\n de: \"Voraussichtliche Zustellung\",\n ru: \"\u041E\u0436\u0438\u0434\u0430\u0435\u043C\u0430\u044F \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0430\",\n pt: \"Previs\u00E3o de entrega\",\n nl: \"Verwachte bezorging\",\n fr: \"Livraison estim\u00E9e\",\n it: \"Consegna prevista\",\n es: \"Entrega estimada\",\n pl: \"Szacowana dostawa\",\n uk: \"\u041E\u0447\u0456\u043A\u0443\u0432\u0430\u043D\u0430 \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0430\",\n \"zh-cn\": \"\u9884\u8BA1\u9001\u8FBE\",\n },\n lastEvent: {\n en: \"Last Event\",\n de: \"Letztes Ereignis\",\n ru: \"\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0435 \u0441\u043E\u0431\u044B\u0442\u0438\u0435\",\n pt: \"\u00DAltimo evento\",\n nl: \"Laatste gebeurtenis\",\n fr: \"Dernier \u00E9v\u00E9nement\",\n it: \"Ultimo evento\",\n es: \"\u00DAltimo evento\",\n pl: \"Ostatnie zdarzenie\",\n uk: \"\u041E\u0441\u0442\u0430\u043D\u043D\u044F \u043F\u043E\u0434\u0456\u044F\",\n \"zh-cn\": \"\u6700\u8FD1\u4E8B\u4EF6\",\n },\n lastLocation: {\n en: \"Last Location\",\n de: \"Letzter Standort\",\n ru: \"\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0435 \u043C\u0435\u0441\u0442\u043E\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\",\n pt: \"\u00DAltima localiza\u00E7\u00E3o\",\n nl: \"Laatste locatie\",\n fr: \"Dernier emplacement\",\n it: \"Ultima posizione\",\n es: \"\u00DAltima ubicaci\u00F3n\",\n pl: \"Ostatnia lokalizacja\",\n uk: \"\u041E\u0441\u0442\u0430\u043D\u043D\u0454 \u043C\u0456\u0441\u0446\u0435\u0437\u043D\u0430\u0445\u043E\u0434\u0436\u0435\u043D\u043D\u044F\",\n \"zh-cn\": \"\u6700\u8FD1\u4F4D\u7F6E\",\n },\n lastUpdated: {\n en: \"Last Updated\",\n de: \"Zuletzt aktualisiert\",\n ru: \"\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0435 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435\",\n pt: \"\u00DAltima atualiza\u00E7\u00E3o\",\n nl: \"Laatst bijgewerkt\",\n fr: \"Derni\u00E8re mise \u00E0 jour\",\n it: \"Ultimo aggiornamento\",\n es: \"\u00DAltima actualizaci\u00F3n\",\n pl: \"Ostatnia aktualizacja\",\n uk: \"\u041E\u0441\u0442\u0430\u043D\u043D\u0454 \u043E\u043D\u043E\u0432\u043B\u0435\u043D\u043D\u044F\",\n \"zh-cn\": \"\u6700\u540E\u66F4\u65B0\",\n },\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Summary states \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n activeCount: {\n en: \"Active Deliveries\",\n de: \"Aktive Sendungen\",\n ru: \"\u0410\u043A\u0442\u0438\u0432\u043D\u044B\u0435 \u043F\u043E\u0441\u044B\u043B\u043A\u0438\",\n pt: \"Entregas ativas\",\n nl: \"Actieve zendingen\",\n fr: \"Livraisons actives\",\n it: \"Spedizioni attive\",\n es: \"Env\u00EDos activos\",\n pl: \"Aktywne przesy\u0142ki\",\n uk: \"\u0410\u043A\u0442\u0438\u0432\u043D\u0456 \u0432\u0456\u0434\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u043D\u044F\",\n \"zh-cn\": \"\u6D3B\u52A8\u4E2D\u7684\u5305\u88F9\",\n },\n todayCount: {\n en: \"Deliveries Today\",\n de: \"Sendungen heute\",\n ru: \"\u0414\u043E\u0441\u0442\u0430\u0432\u043A\u0438 \u0441\u0435\u0433\u043E\u0434\u043D\u044F\",\n pt: \"Entregas hoje\",\n nl: \"Zendingen vandaag\",\n fr: \"Livraisons aujourd'hui\",\n it: \"Spedizioni di oggi\",\n es: \"Entregas de hoy\",\n pl: \"Dostawy dzisiaj\",\n uk: \"\u0414\u043E\u0441\u0442\u0430\u0432\u043A\u0438 \u0441\u044C\u043E\u0433\u043E\u0434\u043D\u0456\",\n \"zh-cn\": \"\u4ECA\u65E5\u9001\u8FBE\",\n },\n summaryDeliveryWindow: {\n en: \"Combined Delivery Window\",\n de: \"Kombiniertes Zustellfenster\",\n ru: \"\u041E\u0431\u044A\u0435\u0434\u0438\u043D\u0451\u043D\u043D\u043E\u0435 \u043E\u043A\u043D\u043E \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0438\",\n pt: \"Janela de entrega combinada\",\n nl: \"Gecombineerd bezorgvenster\",\n fr: \"Cr\u00E9neau de livraison combin\u00E9\",\n it: \"Finestra di consegna combinata\",\n es: \"Ventana de entrega combinada\",\n pl: \"\u0141\u0105czne okno dostawy\",\n uk: \"\u041E\u0431'\u0454\u0434\u043D\u0430\u043D\u0435 \u0432\u0456\u043A\u043D\u043E \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0438\",\n \"zh-cn\": \"\u5408\u5E76\u6D3E\u9001\u65F6\u6BB5\",\n },\n};\n\n/**\n * Translation object for a state name. Pass into `common.name`; ioBroker\n * Admin/vis/Object-Browser localizes automatically.\n *\n * @param key Translation key in {@link STATE_NAMES}.\n */\nexport function tName(key: keyof typeof STATE_NAMES): StateName {\n return STATE_NAMES[key];\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * Localized state names for parcel deliveries in 11 ioBroker system languages.\n *\n * ioBroker accepts plain strings or `{ en, de, ... }` translation objects for\n * `common.name`. Admin, vis and the Object-Browser pick the user's language\n * automatically \u2014 we just hand them the object.\n *\n * Adapter logs (`this.log.*`) stay English by ioBroker convention so that\n * user bug reports remain readable for maintainers regardless of the user's\n * system language.\n */\n\ntype Lang = \"en\" | \"de\" | \"ru\" | \"pt\" | \"nl\" | \"fr\" | \"it\" | \"es\" | \"pl\" | \"uk\" | \"zh-cn\";\n\n/** Translation object as ioBroker expects it. */\nexport type StateName = Record<Lang, string>;\n\n/** State / channel display names (`common.name`). */\nexport const STATE_NAMES: Record<string, StateName> = {\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Per-delivery states \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n carrier: {\n en: \"Carrier\",\n de: \"Versanddienst\",\n ru: \"\u041F\u0435\u0440\u0435\u0432\u043E\u0437\u0447\u0438\u043A\",\n pt: \"Transportadora\",\n nl: \"Vervoerder\",\n fr: \"Transporteur\",\n it: \"Corriere\",\n es: \"Transportista\",\n pl: \"Przewo\u017Anik\",\n uk: \"\u041F\u0435\u0440\u0435\u0432\u0456\u0437\u043D\u0438\u043A\",\n \"zh-cn\": \"\u627F\u8FD0\u5546\",\n },\n status: {\n en: \"Status\",\n de: \"Status\",\n ru: \"\u0421\u0442\u0430\u0442\u0443\u0441\",\n pt: \"Estado\",\n nl: \"Status\",\n fr: \"\u00C9tat\",\n it: \"Stato\",\n es: \"Estado\",\n pl: \"Status\",\n uk: \"\u0421\u0442\u0430\u0442\u0443\u0441\",\n \"zh-cn\": \"\u72B6\u6001\",\n },\n statusCode: {\n en: \"Status Code\",\n de: \"Status-Code\",\n ru: \"\u041A\u043E\u0434 \u0441\u0442\u0430\u0442\u0443\u0441\u0430\",\n pt: \"C\u00F3digo de estado\",\n nl: \"Statuscode\",\n fr: \"Code d'\u00E9tat\",\n it: \"Codice di stato\",\n es: \"C\u00F3digo de estado\",\n pl: \"Kod statusu\",\n uk: \"\u041A\u043E\u0434 \u0441\u0442\u0430\u0442\u0443\u0441\u0443\",\n \"zh-cn\": \"\u72B6\u6001\u4EE3\u7801\",\n },\n description: {\n en: \"Description\",\n de: \"Beschreibung\",\n ru: \"\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435\",\n pt: \"Descri\u00E7\u00E3o\",\n nl: \"Beschrijving\",\n fr: \"Description\",\n it: \"Descrizione\",\n es: \"Descripci\u00F3n\",\n pl: \"Opis\",\n uk: \"\u041E\u043F\u0438\u0441\",\n \"zh-cn\": \"\u63CF\u8FF0\",\n },\n trackingNumber: {\n en: \"Tracking Number\",\n de: \"Sendungsnummer\",\n ru: \"\u0422\u0440\u0435\u043A-\u043D\u043E\u043C\u0435\u0440\",\n pt: \"N\u00FAmero de rastreio\",\n nl: \"Trackingnummer\",\n fr: \"Num\u00E9ro de suivi\",\n it: \"Numero di tracciamento\",\n es: \"N\u00FAmero de seguimiento\",\n pl: \"Numer \u015Bledzenia\",\n uk: \"\u041D\u043E\u043C\u0435\u0440 \u0432\u0456\u0434\u0441\u0442\u0435\u0436\u0435\u043D\u043D\u044F\",\n \"zh-cn\": \"\u8FFD\u8E2A\u53F7\",\n },\n extraInfo: {\n en: \"Extra Information\",\n de: \"Zusatz-Information\",\n ru: \"\u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F\",\n pt: \"Informa\u00E7\u00E3o adicional\",\n nl: \"Extra informatie\",\n fr: \"Informations suppl\u00E9mentaires\",\n it: \"Informazioni aggiuntive\",\n es: \"Informaci\u00F3n adicional\",\n pl: \"Dodatkowe informacje\",\n uk: \"\u0414\u043E\u0434\u0430\u0442\u043A\u043E\u0432\u0430 \u0456\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0456\u044F\",\n \"zh-cn\": \"\u9644\u52A0\u4FE1\u606F\",\n },\n deliveryWindow: {\n en: \"Delivery Window\",\n de: \"Zustellfenster\",\n ru: \"\u041E\u043A\u043D\u043E \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0438\",\n pt: \"Janela de entrega\",\n nl: \"Bezorgvenster\",\n fr: \"Cr\u00E9neau de livraison\",\n it: \"Finestra di consegna\",\n es: \"Ventana de entrega\",\n pl: \"Okno dostawy\",\n uk: \"\u0412\u0456\u043A\u043D\u043E \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0438\",\n \"zh-cn\": \"\u6D3E\u9001\u65F6\u6BB5\",\n },\n deliveryEstimate: {\n en: \"Delivery Estimate\",\n de: \"Voraussichtliche Zustellung\",\n ru: \"\u041E\u0436\u0438\u0434\u0430\u0435\u043C\u0430\u044F \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0430\",\n pt: \"Previs\u00E3o de entrega\",\n nl: \"Verwachte bezorging\",\n fr: \"Livraison estim\u00E9e\",\n it: \"Consegna prevista\",\n es: \"Entrega estimada\",\n pl: \"Szacowana dostawa\",\n uk: \"\u041E\u0447\u0456\u043A\u0443\u0432\u0430\u043D\u0430 \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0430\",\n \"zh-cn\": \"\u9884\u8BA1\u9001\u8FBE\",\n },\n lastEvent: {\n en: \"Last Event\",\n de: \"Letztes Ereignis\",\n ru: \"\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0435 \u0441\u043E\u0431\u044B\u0442\u0438\u0435\",\n pt: \"\u00DAltimo evento\",\n nl: \"Laatste gebeurtenis\",\n fr: \"Dernier \u00E9v\u00E9nement\",\n it: \"Ultimo evento\",\n es: \"\u00DAltimo evento\",\n pl: \"Ostatnie zdarzenie\",\n uk: \"\u041E\u0441\u0442\u0430\u043D\u043D\u044F \u043F\u043E\u0434\u0456\u044F\",\n \"zh-cn\": \"\u6700\u8FD1\u4E8B\u4EF6\",\n },\n lastLocation: {\n en: \"Last Location\",\n de: \"Letzter Standort\",\n ru: \"\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0435 \u043C\u0435\u0441\u0442\u043E\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\",\n pt: \"\u00DAltima localiza\u00E7\u00E3o\",\n nl: \"Laatste locatie\",\n fr: \"Dernier emplacement\",\n it: \"Ultima posizione\",\n es: \"\u00DAltima ubicaci\u00F3n\",\n pl: \"Ostatnia lokalizacja\",\n uk: \"\u041E\u0441\u0442\u0430\u043D\u043D\u0454 \u043C\u0456\u0441\u0446\u0435\u0437\u043D\u0430\u0445\u043E\u0434\u0436\u0435\u043D\u043D\u044F\",\n \"zh-cn\": \"\u6700\u8FD1\u4F4D\u7F6E\",\n },\n lastUpdated: {\n en: \"Last Updated\",\n de: \"Zuletzt aktualisiert\",\n ru: \"\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0435 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435\",\n pt: \"\u00DAltima atualiza\u00E7\u00E3o\",\n nl: \"Laatst bijgewerkt\",\n fr: \"Derni\u00E8re mise \u00E0 jour\",\n it: \"Ultimo aggiornamento\",\n es: \"\u00DAltima actualizaci\u00F3n\",\n pl: \"Ostatnia aktualizacja\",\n uk: \"\u041E\u0441\u0442\u0430\u043D\u043D\u0454 \u043E\u043D\u043E\u0432\u043B\u0435\u043D\u043D\u044F\",\n \"zh-cn\": \"\u6700\u540E\u66F4\u65B0\",\n },\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Summary states \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n activeCount: {\n en: \"Active Deliveries\",\n de: \"Aktive Sendungen\",\n ru: \"\u0410\u043A\u0442\u0438\u0432\u043D\u044B\u0435 \u043F\u043E\u0441\u044B\u043B\u043A\u0438\",\n pt: \"Entregas ativas\",\n nl: \"Actieve zendingen\",\n fr: \"Livraisons actives\",\n it: \"Spedizioni attive\",\n es: \"Env\u00EDos activos\",\n pl: \"Aktywne przesy\u0142ki\",\n uk: \"\u0410\u043A\u0442\u0438\u0432\u043D\u0456 \u0432\u0456\u0434\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u043D\u044F\",\n \"zh-cn\": \"\u6D3B\u52A8\u4E2D\u7684\u5305\u88F9\",\n },\n todayCount: {\n en: \"Deliveries Today\",\n de: \"Sendungen heute\",\n ru: \"\u0414\u043E\u0441\u0442\u0430\u0432\u043A\u0438 \u0441\u0435\u0433\u043E\u0434\u043D\u044F\",\n pt: \"Entregas hoje\",\n nl: \"Zendingen vandaag\",\n fr: \"Livraisons aujourd'hui\",\n it: \"Spedizioni di oggi\",\n es: \"Entregas de hoy\",\n pl: \"Dostawy dzisiaj\",\n uk: \"\u0414\u043E\u0441\u0442\u0430\u0432\u043A\u0438 \u0441\u044C\u043E\u0433\u043E\u0434\u043D\u0456\",\n \"zh-cn\": \"\u4ECA\u65E5\u9001\u8FBE\",\n },\n summaryDeliveryWindow: {\n en: \"Combined Delivery Window\",\n de: \"Kombiniertes Zustellfenster\",\n ru: \"\u041E\u0431\u044A\u0435\u0434\u0438\u043D\u0451\u043D\u043D\u043E\u0435 \u043E\u043A\u043D\u043E \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0438\",\n pt: \"Janela de entrega combinada\",\n nl: \"Gecombineerd bezorgvenster\",\n fr: \"Cr\u00E9neau de livraison combin\u00E9\",\n it: \"Finestra di consegna combinata\",\n es: \"Ventana de entrega combinada\",\n pl: \"\u0141\u0105czne okno dostawy\",\n uk: \"\u041E\u0431'\u0454\u0434\u043D\u0430\u043D\u0435 \u0432\u0456\u043A\u043D\u043E \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0438\",\n \"zh-cn\": \"\u5408\u5E76\u6D3E\u9001\u65F6\u6BB5\",\n },\n};\n\n/** Delivery-estimate labels keyed by language code. */\nexport const ESTIMATE_LABELS: Record<string, Record<string, string>> = {\n de: {\n overdue: \"\u00FCberf\u00E4llig\",\n today: \"heute\",\n tomorrow: \"morgen\",\n days: \"in %d Tagen\",\n },\n en: {\n overdue: \"overdue\",\n today: \"today\",\n tomorrow: \"tomorrow\",\n days: \"in %d days\",\n },\n ru: {\n overdue: \"\u043F\u0440\u043E\u0441\u0440\u043E\u0447\u0435\u043D\u043E\",\n today: \"\u0441\u0435\u0433\u043E\u0434\u043D\u044F\",\n tomorrow: \"\u0437\u0430\u0432\u0442\u0440\u0430\",\n days: \"\u0447\u0435\u0440\u0435\u0437 %d \u0434\u043D.\",\n },\n pt: {\n overdue: \"atrasado\",\n today: \"hoje\",\n tomorrow: \"amanh\u00E3\",\n days: \"em %d dias\",\n },\n nl: {\n overdue: \"te laat\",\n today: \"vandaag\",\n tomorrow: \"morgen\",\n days: \"over %d dagen\",\n },\n fr: {\n overdue: \"en retard\",\n today: \"aujourd'hui\",\n tomorrow: \"demain\",\n days: \"dans %d jours\",\n },\n it: {\n overdue: \"in ritardo\",\n today: \"oggi\",\n tomorrow: \"domani\",\n days: \"tra %d giorni\",\n },\n es: {\n overdue: \"atrasado\",\n today: \"hoy\",\n tomorrow: \"ma\u00F1ana\",\n days: \"en %d d\u00EDas\",\n },\n pl: {\n overdue: \"zaleg\u0142e\",\n today: \"dzisiaj\",\n tomorrow: \"jutro\",\n days: \"za %d dni\",\n },\n uk: {\n overdue: \"\u043F\u0440\u043E\u0441\u0442\u0440\u043E\u0447\u0435\u043D\u043E\",\n today: \"\u0441\u044C\u043E\u0433\u043E\u0434\u043D\u0456\",\n tomorrow: \"\u0437\u0430\u0432\u0442\u0440\u0430\",\n days: \"\u0447\u0435\u0440\u0435\u0437 %d \u0434\u043D.\",\n },\n \"zh-cn\": {\n overdue: \"\u5DF2\u903E\u671F\",\n today: \"\u4ECA\u5929\",\n tomorrow: \"\u660E\u5929\",\n days: \"%d \u5929\u540E\",\n },\n};\n\n/**\n * Translation object for a state name. Pass into `common.name`; ioBroker\n * Admin/vis/Object-Browser localizes automatically.\n *\n * @param key Translation key in {@link STATE_NAMES}.\n */\nexport function tName(key: keyof typeof STATE_NAMES): StateName {\n return STATE_NAMES[key];\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -26,77 +26,6 @@ var import_coerce = require("./coerce");
|
|
|
26
26
|
var import_i18n_states = require("./i18n-states");
|
|
27
27
|
var import_types = require("./types");
|
|
28
28
|
const TRACKABLE_STATUSES = /* @__PURE__ */ new Set([2, 4, 8]);
|
|
29
|
-
function asName(name) {
|
|
30
|
-
return name;
|
|
31
|
-
}
|
|
32
|
-
const ESTIMATE_LABELS = {
|
|
33
|
-
de: {
|
|
34
|
-
overdue: "\xFCberf\xE4llig",
|
|
35
|
-
today: "heute",
|
|
36
|
-
tomorrow: "morgen",
|
|
37
|
-
days: "in %d Tagen"
|
|
38
|
-
},
|
|
39
|
-
en: {
|
|
40
|
-
overdue: "overdue",
|
|
41
|
-
today: "today",
|
|
42
|
-
tomorrow: "tomorrow",
|
|
43
|
-
days: "in %d days"
|
|
44
|
-
},
|
|
45
|
-
ru: {
|
|
46
|
-
overdue: "\u043F\u0440\u043E\u0441\u0440\u043E\u0447\u0435\u043D\u043E",
|
|
47
|
-
today: "\u0441\u0435\u0433\u043E\u0434\u043D\u044F",
|
|
48
|
-
tomorrow: "\u0437\u0430\u0432\u0442\u0440\u0430",
|
|
49
|
-
days: "\u0447\u0435\u0440\u0435\u0437 %d \u0434\u043D."
|
|
50
|
-
},
|
|
51
|
-
pt: {
|
|
52
|
-
overdue: "atrasado",
|
|
53
|
-
today: "hoje",
|
|
54
|
-
tomorrow: "amanh\xE3",
|
|
55
|
-
days: "em %d dias"
|
|
56
|
-
},
|
|
57
|
-
nl: {
|
|
58
|
-
overdue: "te laat",
|
|
59
|
-
today: "vandaag",
|
|
60
|
-
tomorrow: "morgen",
|
|
61
|
-
days: "over %d dagen"
|
|
62
|
-
},
|
|
63
|
-
fr: {
|
|
64
|
-
overdue: "en retard",
|
|
65
|
-
today: "aujourd'hui",
|
|
66
|
-
tomorrow: "demain",
|
|
67
|
-
days: "dans %d jours"
|
|
68
|
-
},
|
|
69
|
-
it: {
|
|
70
|
-
overdue: "in ritardo",
|
|
71
|
-
today: "oggi",
|
|
72
|
-
tomorrow: "domani",
|
|
73
|
-
days: "tra %d giorni"
|
|
74
|
-
},
|
|
75
|
-
es: {
|
|
76
|
-
overdue: "atrasado",
|
|
77
|
-
today: "hoy",
|
|
78
|
-
tomorrow: "ma\xF1ana",
|
|
79
|
-
days: "en %d d\xEDas"
|
|
80
|
-
},
|
|
81
|
-
pl: {
|
|
82
|
-
overdue: "zaleg\u0142e",
|
|
83
|
-
today: "dzisiaj",
|
|
84
|
-
tomorrow: "jutro",
|
|
85
|
-
days: "za %d dni"
|
|
86
|
-
},
|
|
87
|
-
uk: {
|
|
88
|
-
overdue: "\u043F\u0440\u043E\u0441\u0442\u0440\u043E\u0447\u0435\u043D\u043E",
|
|
89
|
-
today: "\u0441\u044C\u043E\u0433\u043E\u0434\u043D\u0456",
|
|
90
|
-
tomorrow: "\u0437\u0430\u0432\u0442\u0440\u0430",
|
|
91
|
-
days: "\u0447\u0435\u0440\u0435\u0437 %d \u0434\u043D."
|
|
92
|
-
},
|
|
93
|
-
"zh-cn": {
|
|
94
|
-
overdue: "\u5DF2\u903E\u671F",
|
|
95
|
-
today: "\u4ECA\u5929",
|
|
96
|
-
tomorrow: "\u660E\u5929",
|
|
97
|
-
days: "%d \u5929\u540E"
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
29
|
function resolveLanguage(language) {
|
|
101
30
|
if (typeof language === "string" && import_types.SUPPORTED_LANGUAGES.includes(language)) {
|
|
102
31
|
return language;
|
|
@@ -244,53 +173,41 @@ class StateManager {
|
|
|
244
173
|
statusText = `Unknown (${statusCode})`;
|
|
245
174
|
}
|
|
246
175
|
await Promise.all([
|
|
247
|
-
this.createAndSet(`${devicePath}.carrier`,
|
|
248
|
-
this.createAndSet(`${devicePath}.status`,
|
|
249
|
-
this.createAndSet(`${devicePath}.statusCode`,
|
|
250
|
-
this.createAndSet(`${devicePath}.description`,
|
|
251
|
-
this.createAndSet(
|
|
252
|
-
|
|
253
|
-
asName((0, import_i18n_states.tName)("trackingNumber")),
|
|
254
|
-
"string",
|
|
255
|
-
"text",
|
|
256
|
-
trackingNumber
|
|
257
|
-
),
|
|
258
|
-
this.createAndSet(`${devicePath}.extraInfo`, asName((0, import_i18n_states.tName)("extraInfo")), "string", "text", extraInfo),
|
|
176
|
+
this.createAndSet(`${devicePath}.carrier`, (0, import_i18n_states.tName)("carrier"), "string", "text", carrierName),
|
|
177
|
+
this.createAndSet(`${devicePath}.status`, (0, import_i18n_states.tName)("status"), "string", "text", statusText),
|
|
178
|
+
this.createAndSet(`${devicePath}.statusCode`, (0, import_i18n_states.tName)("statusCode"), "number", "value", statusCode),
|
|
179
|
+
this.createAndSet(`${devicePath}.description`, (0, import_i18n_states.tName)("description"), "string", "text", description),
|
|
180
|
+
this.createAndSet(`${devicePath}.trackingNumber`, (0, import_i18n_states.tName)("trackingNumber"), "string", "text", trackingNumber),
|
|
181
|
+
this.createAndSet(`${devicePath}.extraInfo`, (0, import_i18n_states.tName)("extraInfo"), "string", "text", extraInfo),
|
|
259
182
|
this.createAndSet(
|
|
260
183
|
`${devicePath}.deliveryWindow`,
|
|
261
|
-
|
|
184
|
+
(0, import_i18n_states.tName)("deliveryWindow"),
|
|
262
185
|
"string",
|
|
263
186
|
"text",
|
|
264
187
|
this.calculateDeliveryWindow(delivery, statusCode)
|
|
265
188
|
),
|
|
266
189
|
this.createAndSet(
|
|
267
190
|
`${devicePath}.deliveryEstimate`,
|
|
268
|
-
|
|
191
|
+
(0, import_i18n_states.tName)("deliveryEstimate"),
|
|
269
192
|
"string",
|
|
270
193
|
"text",
|
|
271
194
|
this.calculateDeliveryEstimate(delivery, statusCode)
|
|
272
195
|
),
|
|
273
196
|
this.createAndSet(
|
|
274
197
|
`${devicePath}.lastEvent`,
|
|
275
|
-
|
|
198
|
+
(0, import_i18n_states.tName)("lastEvent"),
|
|
276
199
|
"string",
|
|
277
200
|
"text",
|
|
278
201
|
this.formatLastEvent(delivery)
|
|
279
202
|
),
|
|
280
203
|
this.createAndSet(
|
|
281
204
|
`${devicePath}.lastLocation`,
|
|
282
|
-
|
|
205
|
+
(0, import_i18n_states.tName)("lastLocation"),
|
|
283
206
|
"string",
|
|
284
207
|
"text",
|
|
285
208
|
this.extractLastLocation(delivery)
|
|
286
209
|
),
|
|
287
|
-
this.createAndSet(
|
|
288
|
-
`${devicePath}.lastUpdated`,
|
|
289
|
-
asName((0, import_i18n_states.tName)("lastUpdated")),
|
|
290
|
-
"string",
|
|
291
|
-
"date",
|
|
292
|
-
(/* @__PURE__ */ new Date()).toISOString()
|
|
293
|
-
)
|
|
210
|
+
this.createAndSet(`${devicePath}.lastUpdated`, (0, import_i18n_states.tName)("lastUpdated"), "string", "date", (/* @__PURE__ */ new Date()).toISOString())
|
|
294
211
|
]);
|
|
295
212
|
}
|
|
296
213
|
/**
|
|
@@ -305,17 +222,11 @@ class StateManager {
|
|
|
305
222
|
`updateSummary: ${activeDeliveries.length} active, ${todayDeliveries.length} expected today`
|
|
306
223
|
);
|
|
307
224
|
await Promise.all([
|
|
308
|
-
this.createAndSet(
|
|
309
|
-
|
|
310
|
-
asName((0, import_i18n_states.tName)("activeCount")),
|
|
311
|
-
"number",
|
|
312
|
-
"value",
|
|
313
|
-
activeDeliveries.length
|
|
314
|
-
),
|
|
315
|
-
this.createAndSet("summary.todayCount", asName((0, import_i18n_states.tName)("todayCount")), "number", "value", todayDeliveries.length),
|
|
225
|
+
this.createAndSet("summary.activeCount", (0, import_i18n_states.tName)("activeCount"), "number", "value", activeDeliveries.length),
|
|
226
|
+
this.createAndSet("summary.todayCount", (0, import_i18n_states.tName)("todayCount"), "number", "value", todayDeliveries.length),
|
|
316
227
|
this.createAndSet(
|
|
317
228
|
"summary.deliveryWindow",
|
|
318
|
-
|
|
229
|
+
(0, import_i18n_states.tName)("summaryDeliveryWindow"),
|
|
319
230
|
"string",
|
|
320
231
|
"text",
|
|
321
232
|
this.calculateCombinedWindow(todayDeliveries)
|
|
@@ -421,7 +332,7 @@ class StateManager {
|
|
|
421
332
|
if (diffDays === null) {
|
|
422
333
|
return "";
|
|
423
334
|
}
|
|
424
|
-
const l = ESTIMATE_LABELS[this.language];
|
|
335
|
+
const l = import_i18n_states.ESTIMATE_LABELS[this.language];
|
|
425
336
|
if (diffDays < 0) {
|
|
426
337
|
return l.overdue;
|
|
427
338
|
}
|
|
@@ -443,17 +354,19 @@ class StateManager {
|
|
|
443
354
|
isToday(delivery, statusCode) {
|
|
444
355
|
return this.computeDiffDays(delivery, statusCode) === 0;
|
|
445
356
|
}
|
|
446
|
-
|
|
447
|
-
* Format the latest tracking event.
|
|
448
|
-
*
|
|
449
|
-
* @param delivery The delivery data
|
|
450
|
-
*/
|
|
451
|
-
formatLastEvent(delivery) {
|
|
357
|
+
getLatestEvent(delivery) {
|
|
452
358
|
if (!Array.isArray(delivery.events) || delivery.events.length === 0) {
|
|
453
|
-
return
|
|
359
|
+
return null;
|
|
454
360
|
}
|
|
455
361
|
const latest = delivery.events[0];
|
|
456
362
|
if (!latest || typeof latest !== "object") {
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
return latest;
|
|
366
|
+
}
|
|
367
|
+
formatLastEvent(delivery) {
|
|
368
|
+
const latest = this.getLatestEvent(delivery);
|
|
369
|
+
if (!latest) {
|
|
457
370
|
return "";
|
|
458
371
|
}
|
|
459
372
|
const parts = [];
|
|
@@ -465,17 +378,9 @@ class StateManager {
|
|
|
465
378
|
}
|
|
466
379
|
return parts.join(" - ");
|
|
467
380
|
}
|
|
468
|
-
/**
|
|
469
|
-
* Extract location from latest event.
|
|
470
|
-
*
|
|
471
|
-
* @param delivery The delivery data
|
|
472
|
-
*/
|
|
473
381
|
extractLastLocation(delivery) {
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
}
|
|
477
|
-
const latest = delivery.events[0];
|
|
478
|
-
if (!latest || typeof latest !== "object") {
|
|
382
|
+
const latest = this.getLatestEvent(delivery);
|
|
383
|
+
if (!latest) {
|
|
479
384
|
return "";
|
|
480
385
|
}
|
|
481
386
|
return typeof latest.location === "string" ? latest.location : "";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/state-manager.ts"],
|
|
4
|
-
"sourcesContent": ["import type { AdapterInstance } from \"@iobroker/adapter-core\";\nimport { coerceFiniteNumber } from \"./coerce\";\nimport type { StateName } from \"./i18n-states\";\nimport { tName } from \"./i18n-states\";\nimport type { ParcelDelivery } from \"./types\";\nimport { STATUS_LABELS, SUPPORTED_LANGUAGES, FALLBACK_LANGUAGE } from \"./types\";\n\n/** Status codes that have expected delivery date/time */\nconst TRACKABLE_STATUSES = new Set([2, 4, 8]);\n\n/**\n * Translation-object cast helper \u2014 ioBroker's `common.name` accepts `StringOrTranslated`.\n *\n * @param name Translation object from {@link STATE_NAMES}.\n */\nfunction asName(name: StateName): ioBroker.StringOrTranslated {\n return name;\n}\n\n/** Delivery-estimate labels keyed by language code. Keys must match STATUS_LABELS. */\nconst ESTIMATE_LABELS: Record<string, Record<string, string>> = {\n de: {\n overdue: \"\u00FCberf\u00E4llig\",\n today: \"heute\",\n tomorrow: \"morgen\",\n days: \"in %d Tagen\",\n },\n en: {\n overdue: \"overdue\",\n today: \"today\",\n tomorrow: \"tomorrow\",\n days: \"in %d days\",\n },\n ru: {\n overdue: \"\u043F\u0440\u043E\u0441\u0440\u043E\u0447\u0435\u043D\u043E\",\n today: \"\u0441\u0435\u0433\u043E\u0434\u043D\u044F\",\n tomorrow: \"\u0437\u0430\u0432\u0442\u0440\u0430\",\n days: \"\u0447\u0435\u0440\u0435\u0437 %d \u0434\u043D.\",\n },\n pt: {\n overdue: \"atrasado\",\n today: \"hoje\",\n tomorrow: \"amanh\u00E3\",\n days: \"em %d dias\",\n },\n nl: {\n overdue: \"te laat\",\n today: \"vandaag\",\n tomorrow: \"morgen\",\n days: \"over %d dagen\",\n },\n fr: {\n overdue: \"en retard\",\n today: \"aujourd'hui\",\n tomorrow: \"demain\",\n days: \"dans %d jours\",\n },\n it: {\n overdue: \"in ritardo\",\n today: \"oggi\",\n tomorrow: \"domani\",\n days: \"tra %d giorni\",\n },\n es: {\n overdue: \"atrasado\",\n today: \"hoy\",\n tomorrow: \"ma\u00F1ana\",\n days: \"en %d d\u00EDas\",\n },\n pl: {\n overdue: \"zaleg\u0142e\",\n today: \"dzisiaj\",\n tomorrow: \"jutro\",\n days: \"za %d dni\",\n },\n uk: {\n overdue: \"\u043F\u0440\u043E\u0441\u0442\u0440\u043E\u0447\u0435\u043D\u043E\",\n today: \"\u0441\u044C\u043E\u0433\u043E\u0434\u043D\u0456\",\n tomorrow: \"\u0437\u0430\u0432\u0442\u0440\u0430\",\n days: \"\u0447\u0435\u0440\u0435\u0437 %d \u0434\u043D.\",\n },\n \"zh-cn\": {\n overdue: \"\u5DF2\u903E\u671F\",\n today: \"\u4ECA\u5929\",\n tomorrow: \"\u660E\u5929\",\n days: \"%d \u5929\u540E\",\n },\n};\n\n/**\n * Resolve a language code to one that has labels. Falls back to English\n * when the system language is not one of the supported ioBroker languages.\n *\n * @param language Raw language code (e.g. from system.config.language)\n */\nexport function resolveLanguage(language: unknown): string {\n if (typeof language === \"string\" && SUPPORTED_LANGUAGES.includes(language)) {\n return language;\n }\n return FALLBACK_LANGUAGE;\n}\n\n/** Manages ioBroker states for parcel deliveries */\nexport class StateManager {\n private adapter: AdapterInstance;\n private language: string;\n /**\n * Cache of state IDs that have already passed `setObjectNotExistsAsync`.\n * Skips repeat DB lookups on the hot path \u2014 each poll touches ~11 states\n * per delivery, and most deliveries see no schema change between polls.\n * On `cleanupDeliveries`, IDs of removed packages are dropped so a re-add\n * triggers a fresh creation.\n */\n private readonly createdIds = new Set<string>();\n\n /**\n * @param adapter The ioBroker adapter instance\n * @param language Language code from system.config.language (falls back to English)\n */\n constructor(adapter: AdapterInstance, language: string) {\n this.adapter = adapter;\n this.language = resolveLanguage(language);\n }\n\n /**\n * Sanitize a string for use as ioBroker object ID (see adapter.FORBIDDEN_CHARS).\n * API-drift guard: returns \"unknown\" for non-string input.\n *\n * @param name Raw value to sanitize (any type)\n */\n sanitize(name: unknown): string {\n if (typeof name !== \"string\") {\n return \"unknown\";\n }\n return (\n name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 50) || \"unknown\"\n );\n }\n\n /**\n * Parse the status code from a delivery. API documents `status_code` as\n * a numeric string, but we accept numbers too and fall back to 0 for drift.\n *\n * @param delivery The delivery to parse\n */\n parseStatus(delivery: ParcelDelivery): number {\n const raw = delivery.status_code as unknown;\n if (typeof raw === \"number\" && Number.isFinite(raw)) {\n return Math.trunc(raw);\n }\n if (typeof raw === \"string\") {\n const n = parseInt(raw, 10);\n return Number.isFinite(n) ? n : 0;\n }\n // v0.4.3 (C2): trace status_code drift (non-string/non-number). Without\n // this, the fallback to 0 (\"delivered\") silently makes packages disappear\n // from active states with no log entry explaining why.\n this.adapter.log.debug(`parseStatus drift: ${JSON.stringify(raw)} (type ${typeof raw}) \u2192 0 (delivered fallback)`);\n return 0;\n }\n\n /**\n * Build a unique package ID from a delivery.\n *\n * v0.4.2 (S3): when the bare `sanitize(tracking_number)` collides with\n * another active package (e.g. two trackings differ only in special\n * chars that strip down to the same id), append a stable hash of the\n * full tracking number so both end up at distinct state IDs.\n *\n * @param delivery The delivery to build an ID for\n */\n packageId(delivery: ParcelDelivery): string {\n let id = this.sanitize(delivery.tracking_number);\n // API-drift guard: only string values extend the id\n if (typeof delivery.extra_information === \"string\" && delivery.extra_information.length > 0) {\n id += `_${this.sanitize(delivery.extra_information)}`;\n }\n // v0.4.2 (S3): collision suffix when two distinct (raw) trackings would\n // collapse to the same id. Bare id is kept as long as it's unique\n // within this poll (back-compat with existing installs).\n const owner = this.idOwner.get(id);\n const rawKey = StateManager.rawIdKey(delivery);\n if (owner !== undefined && owner !== rawKey) {\n const suffixed = `${id}__${StateManager.shortHash(rawKey)}`;\n // v0.4.3 (C3): trace the collision-suffix path. Rare event but the\n // resulting state-id divergence is hard to diagnose without a log.\n this.adapter.log.debug(\n `packageId collision: bare='${id}' owner='${owner}' new='${rawKey}' \u2192 suffixed='${suffixed}'`,\n );\n this.idOwner.set(suffixed, rawKey);\n return suffixed;\n }\n this.idOwner.set(id, rawKey);\n return id;\n }\n\n /**\n * v0.4.2 (S3): build a stable raw-key for collision tracking.\n *\n * @param delivery The delivery whose raw tracking identifies it.\n */\n private static rawIdKey(delivery: ParcelDelivery): string {\n const t = typeof delivery.tracking_number === \"string\" ? delivery.tracking_number : \"\";\n const e = typeof delivery.extra_information === \"string\" ? delivery.extra_information : \"\";\n return `${t}\u0000${e}`;\n }\n\n /**\n * v0.4.2 (S3): FNV-1a 32-bit short hash \u2192 6 hex chars.\n *\n * @param s Input string to hash.\n */\n private static shortHash(s: string): string {\n let h = 0x811c9dc5;\n for (let i = 0; i < s.length; i++) {\n h ^= s.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return (h >>> 0).toString(16).padStart(8, \"0\").slice(0, 6);\n }\n\n /**\n * v0.4.2 (S3): which raw-tracking-key currently \"owns\" each sanitized id\n * within the running poll. Cleared via `resetIdOwners()` between polls so\n * the same delivery keeps its bare id as long as it's unique.\n */\n private readonly idOwner = new Map<string, string>();\n\n /**\n * v0.4.2 (S3): reset the per-poll collision tracker. Call from main.ts\n * before iterating deliveries so the bare id always wins for the first\n * occurrence in each poll.\n */\n resetPollState(): void {\n this.idOwner.clear();\n }\n\n /**\n * Update or create all states for a delivery.\n *\n * @param delivery The delivery data from API\n * @param carrierName Resolved carrier display name\n */\n async updateDelivery(delivery: ParcelDelivery, carrierName: string): Promise<void> {\n const pkgId = this.packageId(delivery);\n const devicePath = `deliveries.${pkgId}`;\n\n const description = typeof delivery.description === \"string\" ? delivery.description : \"\";\n const trackingNumber = typeof delivery.tracking_number === \"string\" ? delivery.tracking_number : \"\";\n const extraInfo = typeof delivery.extra_information === \"string\" ? delivery.extra_information : \"\";\n\n await this.adapter.extendObjectAsync(devicePath, {\n type: \"device\",\n common: {\n name: description || `Package ${trackingNumber || pkgId}`,\n },\n native: {},\n });\n\n const statusCode = this.parseStatus(delivery);\n const labels = STATUS_LABELS[this.language];\n let statusText = labels[statusCode];\n if (!statusText) {\n // v0.4.3 (E3): trace unknown status-code (API drift). A future\n // parcel.app status (e.g. 9, 10) would render as \"Unknown (N)\"\n // without any log clue that the codes table is out of date.\n this.adapter.log.debug(`status code ${statusCode} not in STATUS_LABELS[${this.language}], using fallback`);\n statusText = `Unknown (${statusCode})`;\n }\n\n await Promise.all([\n this.createAndSet(`${devicePath}.carrier`, asName(tName(\"carrier\")), \"string\", \"text\", carrierName),\n this.createAndSet(`${devicePath}.status`, asName(tName(\"status\")), \"string\", \"text\", statusText),\n this.createAndSet(`${devicePath}.statusCode`, asName(tName(\"statusCode\")), \"number\", \"value\", statusCode),\n this.createAndSet(`${devicePath}.description`, asName(tName(\"description\")), \"string\", \"text\", description),\n this.createAndSet(\n `${devicePath}.trackingNumber`,\n asName(tName(\"trackingNumber\")),\n \"string\",\n \"text\",\n trackingNumber,\n ),\n this.createAndSet(`${devicePath}.extraInfo`, asName(tName(\"extraInfo\")), \"string\", \"text\", extraInfo),\n this.createAndSet(\n `${devicePath}.deliveryWindow`,\n asName(tName(\"deliveryWindow\")),\n \"string\",\n \"text\",\n this.calculateDeliveryWindow(delivery, statusCode),\n ),\n this.createAndSet(\n `${devicePath}.deliveryEstimate`,\n asName(tName(\"deliveryEstimate\")),\n \"string\",\n \"text\",\n this.calculateDeliveryEstimate(delivery, statusCode),\n ),\n this.createAndSet(\n `${devicePath}.lastEvent`,\n asName(tName(\"lastEvent\")),\n \"string\",\n \"text\",\n this.formatLastEvent(delivery),\n ),\n this.createAndSet(\n `${devicePath}.lastLocation`,\n asName(tName(\"lastLocation\")),\n \"string\",\n \"text\",\n this.extractLastLocation(delivery),\n ),\n this.createAndSet(\n `${devicePath}.lastUpdated`,\n asName(tName(\"lastUpdated\")),\n \"string\",\n \"date\",\n new Date().toISOString(),\n ),\n ]);\n }\n\n /**\n * Update summary states. Expects already-filtered active deliveries.\n * The `summary` channel itself is declared via io-package.json instanceObjects.\n *\n * @param activeDeliveries Only active (non-delivered) deliveries\n */\n async updateSummary(activeDeliveries: ParcelDelivery[]): Promise<void> {\n const todayDeliveries = activeDeliveries.filter(d => this.isToday(d, this.parseStatus(d)));\n // v0.4.3 (E1): trace summary refresh \u2014 ~144/day at the default poll\n // interval, kept short (counts only).\n this.adapter.log.debug(\n `updateSummary: ${activeDeliveries.length} active, ${todayDeliveries.length} expected today`,\n );\n\n await Promise.all([\n this.createAndSet(\n \"summary.activeCount\",\n asName(tName(\"activeCount\")),\n \"number\",\n \"value\",\n activeDeliveries.length,\n ),\n this.createAndSet(\"summary.todayCount\", asName(tName(\"todayCount\")), \"number\", \"value\", todayDeliveries.length),\n this.createAndSet(\n \"summary.deliveryWindow\",\n asName(tName(\"summaryDeliveryWindow\")),\n \"string\",\n \"text\",\n this.calculateCombinedWindow(todayDeliveries),\n ),\n ]);\n }\n\n /**\n * Remove deliveries that are no longer active.\n *\n * @param activeIds List of currently active package IDs\n */\n async cleanupDeliveries(activeIds: string[]): Promise<void> {\n const activeSet = new Set(activeIds.map(id => `deliveries.${id}`));\n\n const objects = await this.adapter.getObjectViewAsync(\"system\", \"device\", {\n startkey: `${this.adapter.namespace}.deliveries.`,\n endkey: `${this.adapter.namespace}.deliveries.\u9999`,\n });\n if (!objects?.rows) {\n // v0.4.3 (E2): trace the no-op path \u2014 happens on fresh installs or\n // when getObjectViewAsync returns falsy. Without this the early-return\n // is invisible.\n this.adapter.log.debug(\"cleanupDeliveries: no objects view available, skipping\");\n return;\n }\n\n // v0.4.2 (S1): collect first, then delete in parallel. Earlier each\n // stale package took a sequential broker round-trip.\n const toDelete: string[] = [];\n for (const row of objects.rows) {\n const relativeId = row.id.replace(`${this.adapter.namespace}.`, \"\");\n if (relativeId.startsWith(\"deliveries.\") && !activeSet.has(relativeId)) {\n toDelete.push(relativeId);\n }\n }\n\n await Promise.all(\n toDelete.map(async relativeId => {\n await this.adapter.delObjectAsync(relativeId, { recursive: true });\n this.adapter.log.debug(`Removed stale delivery: ${relativeId}`);\n // v0.4.2 (S2): snapshot to array first \u2014 defensive against any future\n // engine that diverges from spec on Set.delete during for-of iteration.\n for (const id of [...this.createdIds]) {\n if (id === relativeId || id.startsWith(`${relativeId}.`)) {\n this.createdIds.delete(id);\n }\n }\n }),\n );\n }\n\n /**\n * Calculate delivery time window \u2014 only from Unix timestamps.\n *\n * @param delivery The delivery data\n * @param statusCode Pre-parsed status code\n */\n private calculateDeliveryWindow(delivery: ParcelDelivery, statusCode: number): string {\n if (!TRACKABLE_STATUSES.has(statusCode)) {\n return \"\";\n }\n\n const formatTime = (timestamp: unknown): string | null => {\n const ts = coerceFiniteNumber(timestamp);\n if (ts === null || ts <= 0) {\n return null;\n }\n const d = new Date(ts * 1000);\n if (Number.isNaN(d.getTime())) {\n return null;\n }\n return `${d.getHours().toString().padStart(2, \"0\")}:${d.getMinutes().toString().padStart(2, \"0\")}`;\n };\n\n const start = formatTime(delivery.timestamp_expected);\n const end = formatTime(delivery.timestamp_expected_end);\n\n if (!start) {\n return \"\";\n }\n return end ? `${start} - ${end}` : start;\n }\n\n /**\n * Days from today to the expected delivery date. Returns null when the\n * delivery has no usable expected date or is in a non-trackable status.\n *\n * @param delivery The delivery data\n * @param statusCode Pre-parsed status code\n */\n private computeDiffDays(delivery: ParcelDelivery, statusCode: number): number | null {\n if (!TRACKABLE_STATUSES.has(statusCode)) {\n return null;\n }\n\n let expectedDate: Date | null = null;\n const ts = coerceFiniteNumber(delivery.timestamp_expected);\n if (ts !== null && ts > 0) {\n expectedDate = new Date(ts * 1000);\n } else if (typeof delivery.date_expected === \"string\" && delivery.date_expected.length > 0) {\n expectedDate = new Date(delivery.date_expected);\n }\n\n if (!expectedDate || isNaN(expectedDate.getTime())) {\n return null;\n }\n\n const now = new Date();\n const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const expectedStart = new Date(expectedDate.getFullYear(), expectedDate.getMonth(), expectedDate.getDate());\n return Math.round((expectedStart.getTime() - todayStart.getTime()) / (1000 * 60 * 60 * 24));\n }\n\n /**\n * Calculate human-readable delivery estimate.\n *\n * @param delivery The delivery data\n * @param statusCode Pre-parsed status code\n */\n private calculateDeliveryEstimate(delivery: ParcelDelivery, statusCode: number): string {\n const diffDays = this.computeDiffDays(delivery, statusCode);\n if (diffDays === null) {\n return \"\";\n }\n const l = ESTIMATE_LABELS[this.language];\n if (diffDays < 0) {\n return l.overdue;\n }\n if (diffDays === 0) {\n return l.today;\n }\n if (diffDays === 1) {\n return l.tomorrow;\n }\n return l.days.replace(\"%d\", String(diffDays));\n }\n\n /**\n * Whether the delivery is expected today. Language-agnostic, used by the\n * summary filter so `todayCount` works across all languages.\n *\n * @param delivery The delivery data\n * @param statusCode Pre-parsed status code\n */\n private isToday(delivery: ParcelDelivery, statusCode: number): boolean {\n return this.computeDiffDays(delivery, statusCode) === 0;\n }\n\n /**\n * Format the latest tracking event.\n *\n * @param delivery The delivery data\n */\n private formatLastEvent(delivery: ParcelDelivery): string {\n if (!Array.isArray(delivery.events) || delivery.events.length === 0) {\n return \"\";\n }\n const latest = delivery.events[0];\n if (!latest || typeof latest !== \"object\") {\n return \"\";\n }\n const parts: string[] = [];\n if (typeof latest.event === \"string\" && latest.event.length > 0) {\n parts.push(latest.event);\n }\n if (typeof latest.date === \"string\" && latest.date.length > 0) {\n parts.push(latest.date);\n }\n return parts.join(\" - \");\n }\n\n /**\n * Extract location from latest event.\n *\n * @param delivery The delivery data\n */\n private extractLastLocation(delivery: ParcelDelivery): string {\n if (!Array.isArray(delivery.events) || delivery.events.length === 0) {\n return \"\";\n }\n const latest = delivery.events[0];\n if (!latest || typeof latest !== \"object\") {\n return \"\";\n }\n return typeof latest.location === \"string\" ? latest.location : \"\";\n }\n\n /**\n * Calculate combined delivery window for today's packages.\n *\n * @param todayDeliveries Deliveries expected today\n */\n private calculateCombinedWindow(todayDeliveries: ParcelDelivery[]): string {\n const windows = todayDeliveries\n .map(d => this.calculateDeliveryWindow(d, this.parseStatus(d)))\n .filter(w => w.length > 0);\n\n if (windows.length === 0) {\n return \"\";\n }\n if (windows.length === 1) {\n return windows[0];\n }\n\n const times: {\n /** Window start */ start: string;\n /** Window end */ end: string;\n }[] = [];\n for (const w of windows) {\n const match = w.match(/(\\d{2}:\\d{2})(?:\\s*-\\s*(\\d{2}:\\d{2}))?/);\n if (match) {\n times.push({ start: match[1], end: match[2] || match[1] });\n }\n }\n\n if (times.length === 0) {\n return \"\";\n }\n\n times.sort((a, b) => a.start.localeCompare(b.start));\n return `${times[0].start} - ${times[times.length - 1].end}`;\n }\n\n /**\n * Create/extend a read-only state and set its value. Skips the\n * `setObjectNotExistsAsync` round-trip once the ID is in the cache \u2014\n * states are static after first creation; only the value changes per poll.\n *\n * @param id State ID relative to adapter namespace\n * @param name Display name (translation object or plain string)\n * @param type Value type\n * @param role ioBroker role\n * @param val Value to set\n */\n private async createAndSet(\n id: string,\n name: ioBroker.StringOrTranslated,\n type: ioBroker.CommonType,\n role: string,\n val: ioBroker.StateValue,\n ): Promise<void> {\n if (!this.createdIds.has(id)) {\n await this.adapter.setObjectNotExistsAsync(id, {\n type: \"state\",\n common: { name, type, role, read: true, write: false },\n native: {},\n });\n this.createdIds.add(id);\n }\n await this.adapter.setStateAsync(id, { val, ack: true });\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,oBAAmC;
|
|
4
|
+
"sourcesContent": ["import type { AdapterInstance } from \"@iobroker/adapter-core\";\nimport { coerceFiniteNumber } from \"./coerce\";\nimport { ESTIMATE_LABELS, tName } from \"./i18n-states\";\nimport type { ParcelDelivery, ParcelEvent } from \"./types\";\nimport { STATUS_LABELS, SUPPORTED_LANGUAGES, FALLBACK_LANGUAGE } from \"./types\";\n\n/** Status codes that have expected delivery date/time */\nconst TRACKABLE_STATUSES = new Set([2, 4, 8]);\n\n/**\n * Resolve a language code to one that has labels. Falls back to English\n * when the system language is not one of the supported ioBroker languages.\n *\n * @param language Raw language code (e.g. from system.config.language)\n */\nexport function resolveLanguage(language: unknown): string {\n if (typeof language === \"string\" && SUPPORTED_LANGUAGES.includes(language)) {\n return language;\n }\n return FALLBACK_LANGUAGE;\n}\n\n/** Manages ioBroker states for parcel deliveries */\nexport class StateManager {\n private adapter: AdapterInstance;\n private language: string;\n /**\n * Cache of state IDs that have already passed `setObjectNotExistsAsync`.\n * Skips repeat DB lookups on the hot path \u2014 each poll touches ~11 states\n * per delivery, and most deliveries see no schema change between polls.\n * On `cleanupDeliveries`, IDs of removed packages are dropped so a re-add\n * triggers a fresh creation.\n */\n private readonly createdIds = new Set<string>();\n\n /**\n * @param adapter The ioBroker adapter instance\n * @param language Language code from system.config.language (falls back to English)\n */\n constructor(adapter: AdapterInstance, language: string) {\n this.adapter = adapter;\n this.language = resolveLanguage(language);\n }\n\n /**\n * Sanitize a string for use as ioBroker object ID (see adapter.FORBIDDEN_CHARS).\n * API-drift guard: returns \"unknown\" for non-string input.\n *\n * @param name Raw value to sanitize (any type)\n */\n sanitize(name: unknown): string {\n if (typeof name !== \"string\") {\n return \"unknown\";\n }\n return (\n name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 50) || \"unknown\"\n );\n }\n\n /**\n * Parse the status code from a delivery. API documents `status_code` as\n * a numeric string, but we accept numbers too and fall back to 0 for drift.\n *\n * @param delivery The delivery to parse\n */\n parseStatus(delivery: ParcelDelivery): number {\n const raw = delivery.status_code as unknown;\n if (typeof raw === \"number\" && Number.isFinite(raw)) {\n return Math.trunc(raw);\n }\n if (typeof raw === \"string\") {\n const n = parseInt(raw, 10);\n return Number.isFinite(n) ? n : 0;\n }\n // v0.4.3 (C2): trace status_code drift (non-string/non-number). Without\n // this, the fallback to 0 (\"delivered\") silently makes packages disappear\n // from active states with no log entry explaining why.\n this.adapter.log.debug(`parseStatus drift: ${JSON.stringify(raw)} (type ${typeof raw}) \u2192 0 (delivered fallback)`);\n return 0;\n }\n\n /**\n * Build a unique package ID from a delivery.\n *\n * v0.4.2 (S3): when the bare `sanitize(tracking_number)` collides with\n * another active package (e.g. two trackings differ only in special\n * chars that strip down to the same id), append a stable hash of the\n * full tracking number so both end up at distinct state IDs.\n *\n * @param delivery The delivery to build an ID for\n */\n packageId(delivery: ParcelDelivery): string {\n let id = this.sanitize(delivery.tracking_number);\n // API-drift guard: only string values extend the id\n if (typeof delivery.extra_information === \"string\" && delivery.extra_information.length > 0) {\n id += `_${this.sanitize(delivery.extra_information)}`;\n }\n // v0.4.2 (S3): collision suffix when two distinct (raw) trackings would\n // collapse to the same id. Bare id is kept as long as it's unique\n // within this poll (back-compat with existing installs).\n const owner = this.idOwner.get(id);\n const rawKey = StateManager.rawIdKey(delivery);\n if (owner !== undefined && owner !== rawKey) {\n const suffixed = `${id}__${StateManager.shortHash(rawKey)}`;\n // v0.4.3 (C3): trace the collision-suffix path. Rare event but the\n // resulting state-id divergence is hard to diagnose without a log.\n this.adapter.log.debug(\n `packageId collision: bare='${id}' owner='${owner}' new='${rawKey}' \u2192 suffixed='${suffixed}'`,\n );\n this.idOwner.set(suffixed, rawKey);\n return suffixed;\n }\n this.idOwner.set(id, rawKey);\n return id;\n }\n\n /**\n * v0.4.2 (S3): build a stable raw-key for collision tracking.\n *\n * @param delivery The delivery whose raw tracking identifies it.\n */\n private static rawIdKey(delivery: ParcelDelivery): string {\n const t = typeof delivery.tracking_number === \"string\" ? delivery.tracking_number : \"\";\n const e = typeof delivery.extra_information === \"string\" ? delivery.extra_information : \"\";\n return `${t}\u0000${e}`;\n }\n\n /**\n * v0.4.2 (S3): FNV-1a 32-bit short hash \u2192 6 hex chars.\n *\n * @param s Input string to hash.\n */\n private static shortHash(s: string): string {\n let h = 0x811c9dc5;\n for (let i = 0; i < s.length; i++) {\n h ^= s.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return (h >>> 0).toString(16).padStart(8, \"0\").slice(0, 6);\n }\n\n /**\n * v0.4.2 (S3): which raw-tracking-key currently \"owns\" each sanitized id\n * within the running poll. Cleared via `resetIdOwners()` between polls so\n * the same delivery keeps its bare id as long as it's unique.\n */\n private readonly idOwner = new Map<string, string>();\n\n /**\n * v0.4.2 (S3): reset the per-poll collision tracker. Call from main.ts\n * before iterating deliveries so the bare id always wins for the first\n * occurrence in each poll.\n */\n resetPollState(): void {\n this.idOwner.clear();\n }\n\n /**\n * Update or create all states for a delivery.\n *\n * @param delivery The delivery data from API\n * @param carrierName Resolved carrier display name\n */\n async updateDelivery(delivery: ParcelDelivery, carrierName: string): Promise<void> {\n const pkgId = this.packageId(delivery);\n const devicePath = `deliveries.${pkgId}`;\n\n const description = typeof delivery.description === \"string\" ? delivery.description : \"\";\n const trackingNumber = typeof delivery.tracking_number === \"string\" ? delivery.tracking_number : \"\";\n const extraInfo = typeof delivery.extra_information === \"string\" ? delivery.extra_information : \"\";\n\n await this.adapter.extendObjectAsync(devicePath, {\n type: \"device\",\n common: {\n name: description || `Package ${trackingNumber || pkgId}`,\n },\n native: {},\n });\n\n const statusCode = this.parseStatus(delivery);\n const labels = STATUS_LABELS[this.language];\n let statusText = labels[statusCode];\n if (!statusText) {\n // v0.4.3 (E3): trace unknown status-code (API drift). A future\n // parcel.app status (e.g. 9, 10) would render as \"Unknown (N)\"\n // without any log clue that the codes table is out of date.\n this.adapter.log.debug(`status code ${statusCode} not in STATUS_LABELS[${this.language}], using fallback`);\n statusText = `Unknown (${statusCode})`;\n }\n\n await Promise.all([\n this.createAndSet(`${devicePath}.carrier`, tName(\"carrier\"), \"string\", \"text\", carrierName),\n this.createAndSet(`${devicePath}.status`, tName(\"status\"), \"string\", \"text\", statusText),\n this.createAndSet(`${devicePath}.statusCode`, tName(\"statusCode\"), \"number\", \"value\", statusCode),\n this.createAndSet(`${devicePath}.description`, tName(\"description\"), \"string\", \"text\", description),\n this.createAndSet(`${devicePath}.trackingNumber`, tName(\"trackingNumber\"), \"string\", \"text\", trackingNumber),\n this.createAndSet(`${devicePath}.extraInfo`, tName(\"extraInfo\"), \"string\", \"text\", extraInfo),\n this.createAndSet(\n `${devicePath}.deliveryWindow`,\n tName(\"deliveryWindow\"),\n \"string\",\n \"text\",\n this.calculateDeliveryWindow(delivery, statusCode),\n ),\n this.createAndSet(\n `${devicePath}.deliveryEstimate`,\n tName(\"deliveryEstimate\"),\n \"string\",\n \"text\",\n this.calculateDeliveryEstimate(delivery, statusCode),\n ),\n this.createAndSet(\n `${devicePath}.lastEvent`,\n tName(\"lastEvent\"),\n \"string\",\n \"text\",\n this.formatLastEvent(delivery),\n ),\n this.createAndSet(\n `${devicePath}.lastLocation`,\n tName(\"lastLocation\"),\n \"string\",\n \"text\",\n this.extractLastLocation(delivery),\n ),\n this.createAndSet(`${devicePath}.lastUpdated`, tName(\"lastUpdated\"), \"string\", \"date\", new Date().toISOString()),\n ]);\n }\n\n /**\n * Update summary states. Expects already-filtered active deliveries.\n * The `summary` channel itself is declared via io-package.json instanceObjects.\n *\n * @param activeDeliveries Only active (non-delivered) deliveries\n */\n async updateSummary(activeDeliveries: ParcelDelivery[]): Promise<void> {\n const todayDeliveries = activeDeliveries.filter(d => this.isToday(d, this.parseStatus(d)));\n // v0.4.3 (E1): trace summary refresh \u2014 ~144/day at the default poll\n // interval, kept short (counts only).\n this.adapter.log.debug(\n `updateSummary: ${activeDeliveries.length} active, ${todayDeliveries.length} expected today`,\n );\n\n await Promise.all([\n this.createAndSet(\"summary.activeCount\", tName(\"activeCount\"), \"number\", \"value\", activeDeliveries.length),\n this.createAndSet(\"summary.todayCount\", tName(\"todayCount\"), \"number\", \"value\", todayDeliveries.length),\n this.createAndSet(\n \"summary.deliveryWindow\",\n tName(\"summaryDeliveryWindow\"),\n \"string\",\n \"text\",\n this.calculateCombinedWindow(todayDeliveries),\n ),\n ]);\n }\n\n /**\n * Remove deliveries that are no longer active.\n *\n * @param activeIds List of currently active package IDs\n */\n async cleanupDeliveries(activeIds: string[]): Promise<void> {\n const activeSet = new Set(activeIds.map(id => `deliveries.${id}`));\n\n const objects = await this.adapter.getObjectViewAsync(\"system\", \"device\", {\n startkey: `${this.adapter.namespace}.deliveries.`,\n endkey: `${this.adapter.namespace}.deliveries.\u9999`,\n });\n if (!objects?.rows) {\n // v0.4.3 (E2): trace the no-op path \u2014 happens on fresh installs or\n // when getObjectViewAsync returns falsy. Without this the early-return\n // is invisible.\n this.adapter.log.debug(\"cleanupDeliveries: no objects view available, skipping\");\n return;\n }\n\n // v0.4.2 (S1): collect first, then delete in parallel. Earlier each\n // stale package took a sequential broker round-trip.\n const toDelete: string[] = [];\n for (const row of objects.rows) {\n const relativeId = row.id.replace(`${this.adapter.namespace}.`, \"\");\n if (relativeId.startsWith(\"deliveries.\") && !activeSet.has(relativeId)) {\n toDelete.push(relativeId);\n }\n }\n\n await Promise.all(\n toDelete.map(async relativeId => {\n await this.adapter.delObjectAsync(relativeId, { recursive: true });\n this.adapter.log.debug(`Removed stale delivery: ${relativeId}`);\n // v0.4.2 (S2): snapshot to array first \u2014 defensive against any future\n // engine that diverges from spec on Set.delete during for-of iteration.\n for (const id of [...this.createdIds]) {\n if (id === relativeId || id.startsWith(`${relativeId}.`)) {\n this.createdIds.delete(id);\n }\n }\n }),\n );\n }\n\n /**\n * Calculate delivery time window \u2014 only from Unix timestamps.\n *\n * @param delivery The delivery data\n * @param statusCode Pre-parsed status code\n */\n private calculateDeliveryWindow(delivery: ParcelDelivery, statusCode: number): string {\n if (!TRACKABLE_STATUSES.has(statusCode)) {\n return \"\";\n }\n\n const formatTime = (timestamp: unknown): string | null => {\n const ts = coerceFiniteNumber(timestamp);\n if (ts === null || ts <= 0) {\n return null;\n }\n const d = new Date(ts * 1000);\n if (Number.isNaN(d.getTime())) {\n return null;\n }\n return `${d.getHours().toString().padStart(2, \"0\")}:${d.getMinutes().toString().padStart(2, \"0\")}`;\n };\n\n const start = formatTime(delivery.timestamp_expected);\n const end = formatTime(delivery.timestamp_expected_end);\n\n if (!start) {\n return \"\";\n }\n return end ? `${start} - ${end}` : start;\n }\n\n /**\n * Days from today to the expected delivery date. Returns null when the\n * delivery has no usable expected date or is in a non-trackable status.\n *\n * @param delivery The delivery data\n * @param statusCode Pre-parsed status code\n */\n private computeDiffDays(delivery: ParcelDelivery, statusCode: number): number | null {\n if (!TRACKABLE_STATUSES.has(statusCode)) {\n return null;\n }\n\n let expectedDate: Date | null = null;\n const ts = coerceFiniteNumber(delivery.timestamp_expected);\n if (ts !== null && ts > 0) {\n expectedDate = new Date(ts * 1000);\n } else if (typeof delivery.date_expected === \"string\" && delivery.date_expected.length > 0) {\n expectedDate = new Date(delivery.date_expected);\n }\n\n if (!expectedDate || isNaN(expectedDate.getTime())) {\n return null;\n }\n\n const now = new Date();\n const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const expectedStart = new Date(expectedDate.getFullYear(), expectedDate.getMonth(), expectedDate.getDate());\n return Math.round((expectedStart.getTime() - todayStart.getTime()) / (1000 * 60 * 60 * 24));\n }\n\n /**\n * Calculate human-readable delivery estimate.\n *\n * @param delivery The delivery data\n * @param statusCode Pre-parsed status code\n */\n private calculateDeliveryEstimate(delivery: ParcelDelivery, statusCode: number): string {\n const diffDays = this.computeDiffDays(delivery, statusCode);\n if (diffDays === null) {\n return \"\";\n }\n const l = ESTIMATE_LABELS[this.language];\n if (diffDays < 0) {\n return l.overdue;\n }\n if (diffDays === 0) {\n return l.today;\n }\n if (diffDays === 1) {\n return l.tomorrow;\n }\n return l.days.replace(\"%d\", String(diffDays));\n }\n\n /**\n * Whether the delivery is expected today. Language-agnostic, used by the\n * summary filter so `todayCount` works across all languages.\n *\n * @param delivery The delivery data\n * @param statusCode Pre-parsed status code\n */\n private isToday(delivery: ParcelDelivery, statusCode: number): boolean {\n return this.computeDiffDays(delivery, statusCode) === 0;\n }\n\n private getLatestEvent(delivery: ParcelDelivery): ParcelEvent | null {\n if (!Array.isArray(delivery.events) || delivery.events.length === 0) {\n return null;\n }\n const latest = delivery.events[0];\n if (!latest || typeof latest !== \"object\") {\n return null;\n }\n return latest;\n }\n\n private formatLastEvent(delivery: ParcelDelivery): string {\n const latest = this.getLatestEvent(delivery);\n if (!latest) {\n return \"\";\n }\n const parts: string[] = [];\n if (typeof latest.event === \"string\" && latest.event.length > 0) {\n parts.push(latest.event);\n }\n if (typeof latest.date === \"string\" && latest.date.length > 0) {\n parts.push(latest.date);\n }\n return parts.join(\" - \");\n }\n\n private extractLastLocation(delivery: ParcelDelivery): string {\n const latest = this.getLatestEvent(delivery);\n if (!latest) {\n return \"\";\n }\n return typeof latest.location === \"string\" ? latest.location : \"\";\n }\n\n /**\n * Calculate combined delivery window for today's packages.\n *\n * @param todayDeliveries Deliveries expected today\n */\n private calculateCombinedWindow(todayDeliveries: ParcelDelivery[]): string {\n const windows = todayDeliveries\n .map(d => this.calculateDeliveryWindow(d, this.parseStatus(d)))\n .filter(w => w.length > 0);\n\n if (windows.length === 0) {\n return \"\";\n }\n if (windows.length === 1) {\n return windows[0];\n }\n\n const times: {\n /** Window start */ start: string;\n /** Window end */ end: string;\n }[] = [];\n for (const w of windows) {\n const match = w.match(/(\\d{2}:\\d{2})(?:\\s*-\\s*(\\d{2}:\\d{2}))?/);\n if (match) {\n times.push({ start: match[1], end: match[2] || match[1] });\n }\n }\n\n if (times.length === 0) {\n return \"\";\n }\n\n times.sort((a, b) => a.start.localeCompare(b.start));\n return `${times[0].start} - ${times[times.length - 1].end}`;\n }\n\n /**\n * Create/extend a read-only state and set its value. Skips the\n * `setObjectNotExistsAsync` round-trip once the ID is in the cache \u2014\n * states are static after first creation; only the value changes per poll.\n *\n * @param id State ID relative to adapter namespace\n * @param name Display name (translation object or plain string)\n * @param type Value type\n * @param role ioBroker role\n * @param val Value to set\n */\n private async createAndSet(\n id: string,\n name: ioBroker.StringOrTranslated,\n type: ioBroker.CommonType,\n role: string,\n val: ioBroker.StateValue,\n ): Promise<void> {\n if (!this.createdIds.has(id)) {\n await this.adapter.setObjectNotExistsAsync(id, {\n type: \"state\",\n common: { name, type, role, read: true, write: false },\n native: {},\n });\n this.createdIds.add(id);\n }\n await this.adapter.setStateAsync(id, { val, ack: true });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "parcelapp",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.5",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.4.5": {
|
|
7
|
+
"en": "Fixed adapter icon not displaying in some admin environments (Content Security Policy).",
|
|
8
|
+
"de": "Adapter-Icon wird jetzt auch in Admin-Umgebungen mit Content Security Policy korrekt angezeigt.",
|
|
9
|
+
"ru": "Исправлено отображение иконки адаптера в средах администрирования с Content Security Policy.",
|
|
10
|
+
"pt": "Corrigido o ícone do adaptador que não era exibido em alguns ambientes de administração (Content Security Policy).",
|
|
11
|
+
"nl": "Adapter-icoon wordt nu correct weergegeven in admin-omgevingen met Content Security Policy.",
|
|
12
|
+
"fr": "Correction de l'icône de l'adaptateur qui ne s'affichait pas dans certains environnements d'administration (Content Security Policy).",
|
|
13
|
+
"it": "Corretta l'icona dell'adattatore che non veniva visualizzata in alcuni ambienti di amministrazione (Content Security Policy).",
|
|
14
|
+
"es": "Corregido el icono del adaptador que no se mostraba en algunos entornos de administración (Content Security Policy).",
|
|
15
|
+
"pl": "Naprawiono wyświetlanie ikony adaptera w niektórych środowiskach administracyjnych (Content Security Policy).",
|
|
16
|
+
"uk": "Виправлено відображення іконки адаптера в деяких середовищах адміністрування (Content Security Policy).",
|
|
17
|
+
"zh-cn": "修复了在某些管理环境中适配器图标因内容安全策略而无法显示的问题。"
|
|
18
|
+
},
|
|
6
19
|
"0.4.4": {
|
|
7
20
|
"en": "Adapter shuts down cleanly even if Test Connection was still running — the test request is now aborted at unload.",
|
|
8
21
|
"de": "Adapter fährt sauber herunter, auch wenn Test Connection noch lief — die Test-Anfrage wird jetzt beim Unload abgebrochen.",
|
|
@@ -80,19 +93,6 @@
|
|
|
80
93
|
"pl": "Dokumentacja: notatki wydania przepisane w przyjaznym dla użytkownika stylu we wszystkich językach.",
|
|
81
94
|
"uk": "Документація: нотатки до релізу переписано у дружньому до користувача стилі усіма мовами.",
|
|
82
95
|
"zh-cn": "文档:所有语言的发布说明已重写为用户友好的风格。"
|
|
83
|
-
},
|
|
84
|
-
"0.3.1": {
|
|
85
|
-
"en": "Documentation cleanup. No code changes.",
|
|
86
|
-
"de": "Dokumentations-Bereinigung. Keine Code-Änderungen.",
|
|
87
|
-
"ru": "Очистка документации. Без изменений в коде.",
|
|
88
|
-
"pt": "Limpeza da documentação. Sem alterações de código.",
|
|
89
|
-
"nl": "Documentatie-opschoning. Geen code-wijzigingen.",
|
|
90
|
-
"fr": "Nettoyage de la documentation. Aucune modification de code.",
|
|
91
|
-
"it": "Pulizia della documentazione. Nessuna modifica al codice.",
|
|
92
|
-
"es": "Limpieza de documentación. Sin cambios de código.",
|
|
93
|
-
"pl": "Czyszczenie dokumentacji. Bez zmian w kodzie.",
|
|
94
|
-
"uk": "Очищення документації. Без змін у коді.",
|
|
95
|
-
"zh-cn": "文档清理。代码无变化。"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"titleLang": {
|
|
@@ -138,7 +138,7 @@
|
|
|
138
138
|
},
|
|
139
139
|
"platform": "Javascript/Node.js",
|
|
140
140
|
"icon": "parcelapp.svg",
|
|
141
|
-
"extIcon": "https://
|
|
141
|
+
"extIcon": "https://cdn.jsdelivr.net/gh/krobipd/ioBroker.parcelapp@main/admin/parcelapp.svg",
|
|
142
142
|
"readme": "https://github.com/krobipd/ioBroker.parcelapp/blob/main/README.md",
|
|
143
143
|
"enabled": true,
|
|
144
144
|
"tier": 3,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.parcelapp",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.5",
|
|
4
4
|
"description": "ioBroker adapter for the parcel.app API",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "krobi",
|
|
@@ -34,20 +34,19 @@
|
|
|
34
34
|
"@iobroker/adapter-core": "^3.3.2"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@alcalzone/release-script": "^5.
|
|
38
|
-
"@alcalzone/release-script-plugin-iobroker": "^5.
|
|
39
|
-
"@alcalzone/release-script-plugin-license": "^5.
|
|
37
|
+
"@alcalzone/release-script": "^5.2.0",
|
|
38
|
+
"@alcalzone/release-script-plugin-iobroker": "^5.2.0",
|
|
39
|
+
"@alcalzone/release-script-plugin-license": "^5.2.0",
|
|
40
40
|
"@iobroker/adapter-dev": "^1.5.0",
|
|
41
|
-
"@iobroker/eslint-config": "^2.
|
|
41
|
+
"@iobroker/eslint-config": "^2.3.4",
|
|
42
42
|
"@iobroker/testing": "^5.2.2",
|
|
43
43
|
"@tsconfig/node22": "^22.0.5",
|
|
44
|
-
"@types/iobroker": "npm:@iobroker/types@^7.1.
|
|
44
|
+
"@types/iobroker": "npm:@iobroker/types@^7.1.2",
|
|
45
45
|
"@types/node": "^22.19.17",
|
|
46
|
-
"
|
|
46
|
+
"@vitest/coverage-v8": "^4.1.6",
|
|
47
47
|
"rimraf": "^6.1.3",
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"typescript": "~5.9.3"
|
|
48
|
+
"typescript": "~6.0.3",
|
|
49
|
+
"vitest": "^4.1.6"
|
|
51
50
|
},
|
|
52
51
|
"files": [
|
|
53
52
|
"admin",
|
|
@@ -61,11 +60,11 @@
|
|
|
61
60
|
"build": "build-adapter ts",
|
|
62
61
|
"watch": "build-adapter ts --watch",
|
|
63
62
|
"check": "tsc --noEmit",
|
|
64
|
-
"test:ts": "
|
|
63
|
+
"test:ts": "vitest run",
|
|
65
64
|
"test:package": "mocha test/package --exit",
|
|
66
65
|
"test:integration": "mocha test/integration --exit",
|
|
67
66
|
"test": "npm run test:ts && npm run test:package",
|
|
68
|
-
"coverage": "
|
|
67
|
+
"coverage": "vitest run --coverage",
|
|
69
68
|
"translate": "translate-adapter",
|
|
70
69
|
"lint": "eslint",
|
|
71
70
|
"lint:fix": "eslint --fix",
|
|
@@ -73,26 +72,6 @@
|
|
|
73
72
|
"format:check": "prettier --check .",
|
|
74
73
|
"release": "release-script"
|
|
75
74
|
},
|
|
76
|
-
"nyc": {
|
|
77
|
-
"include": [
|
|
78
|
-
"src/**/*.ts"
|
|
79
|
-
],
|
|
80
|
-
"exclude": [
|
|
81
|
-
"src/**/*.test.ts"
|
|
82
|
-
],
|
|
83
|
-
"extension": [
|
|
84
|
-
".ts"
|
|
85
|
-
],
|
|
86
|
-
"require": [
|
|
87
|
-
"ts-node/register"
|
|
88
|
-
],
|
|
89
|
-
"reporter": [
|
|
90
|
-
"text-summary",
|
|
91
|
-
"html"
|
|
92
|
-
],
|
|
93
|
-
"sourceMap": true,
|
|
94
|
-
"instrument": true
|
|
95
|
-
},
|
|
96
75
|
"bugs": {
|
|
97
76
|
"url": "https://github.com/krobipd/ioBroker.parcelapp/issues"
|
|
98
77
|
},
|