iobroker.parcelapp 0.2.13 → 0.2.15
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 +19 -17
- package/admin/i18n/de/translations.json +0 -5
- package/admin/i18n/en/translations.json +0 -5
- package/admin/i18n/es/translations.json +0 -5
- package/admin/i18n/fr/translations.json +0 -5
- package/admin/i18n/it/translations.json +0 -5
- package/admin/i18n/nl/translations.json +0 -5
- package/admin/i18n/pl/translations.json +0 -5
- package/admin/i18n/pt/translations.json +0 -5
- package/admin/i18n/ru/translations.json +0 -5
- package/admin/i18n/uk/translations.json +0 -5
- package/admin/i18n/zh-cn/translations.json +0 -5
- package/admin/jsonConfig.json +0 -17
- package/build/lib/state-manager.js +107 -24
- package/build/lib/state-manager.js.map +2 -2
- package/build/lib/types.js +134 -23
- package/build/lib/types.js.map +2 -2
- package/build/main.js +36 -5
- package/build/main.js.map +2 -2
- package/io-package.json +123 -84
- package/package.json +4 -4
package/build/lib/types.js
CHANGED
|
@@ -18,35 +18,146 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var types_exports = {};
|
|
20
20
|
__export(types_exports, {
|
|
21
|
+
FALLBACK_LANGUAGE: () => FALLBACK_LANGUAGE,
|
|
22
|
+
STATUS_LABELS: () => STATUS_LABELS,
|
|
21
23
|
STATUS_LABELS_DE: () => STATUS_LABELS_DE,
|
|
22
|
-
STATUS_LABELS_EN: () => STATUS_LABELS_EN
|
|
24
|
+
STATUS_LABELS_EN: () => STATUS_LABELS_EN,
|
|
25
|
+
SUPPORTED_LANGUAGES: () => SUPPORTED_LANGUAGES
|
|
23
26
|
});
|
|
24
27
|
module.exports = __toCommonJS(types_exports);
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
28
|
+
const STATUS_LABELS = {
|
|
29
|
+
de: {
|
|
30
|
+
0: "Zugestellt",
|
|
31
|
+
1: "Eingefroren",
|
|
32
|
+
2: "Unterwegs",
|
|
33
|
+
3: "Abholung erwartet",
|
|
34
|
+
4: "In Zustellung",
|
|
35
|
+
5: "Nicht gefunden",
|
|
36
|
+
6: "Zustellversuch gescheitert",
|
|
37
|
+
7: "Ausnahme",
|
|
38
|
+
8: "Registriert"
|
|
39
|
+
},
|
|
40
|
+
en: {
|
|
41
|
+
0: "Delivered",
|
|
42
|
+
1: "Frozen",
|
|
43
|
+
2: "In Transit",
|
|
44
|
+
3: "Awaiting Pickup",
|
|
45
|
+
4: "Out for Delivery",
|
|
46
|
+
5: "Not Found",
|
|
47
|
+
6: "Delivery Attempt Failed",
|
|
48
|
+
7: "Exception",
|
|
49
|
+
8: "Info Received"
|
|
50
|
+
},
|
|
51
|
+
ru: {
|
|
52
|
+
0: "\u0414\u043E\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u043E",
|
|
53
|
+
1: "\u0417\u0430\u043C\u043E\u0440\u043E\u0436\u0435\u043D\u043E",
|
|
54
|
+
2: "\u0412 \u043F\u0443\u0442\u0438",
|
|
55
|
+
3: "\u041E\u0436\u0438\u0434\u0430\u0435\u0442 \u043F\u043E\u043B\u0443\u0447\u0435\u043D\u0438\u044F",
|
|
56
|
+
4: "\u0414\u043E\u0441\u0442\u0430\u0432\u043B\u044F\u0435\u0442\u0441\u044F",
|
|
57
|
+
5: "\u041D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E",
|
|
58
|
+
6: "\u041D\u0435\u0443\u0434\u0430\u0447\u043D\u0430\u044F \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0430",
|
|
59
|
+
7: "\u0418\u0441\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435",
|
|
60
|
+
8: "\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u043E"
|
|
61
|
+
},
|
|
62
|
+
pt: {
|
|
63
|
+
0: "Entregue",
|
|
64
|
+
1: "Congelado",
|
|
65
|
+
2: "Em tr\xE2nsito",
|
|
66
|
+
3: "Aguardando recolha",
|
|
67
|
+
4: "Em entrega",
|
|
68
|
+
5: "N\xE3o encontrado",
|
|
69
|
+
6: "Tentativa de entrega falhou",
|
|
70
|
+
7: "Exce\xE7\xE3o",
|
|
71
|
+
8: "Registado"
|
|
72
|
+
},
|
|
73
|
+
nl: {
|
|
74
|
+
0: "Bezorgd",
|
|
75
|
+
1: "Bevroren",
|
|
76
|
+
2: "Onderweg",
|
|
77
|
+
3: "Wacht op ophaling",
|
|
78
|
+
4: "Wordt bezorgd",
|
|
79
|
+
5: "Niet gevonden",
|
|
80
|
+
6: "Bezorgpoging mislukt",
|
|
81
|
+
7: "Uitzondering",
|
|
82
|
+
8: "Geregistreerd"
|
|
83
|
+
},
|
|
84
|
+
fr: {
|
|
85
|
+
0: "Livr\xE9",
|
|
86
|
+
1: "Gel\xE9",
|
|
87
|
+
2: "En transit",
|
|
88
|
+
3: "En attente de retrait",
|
|
89
|
+
4: "En cours de livraison",
|
|
90
|
+
5: "Introuvable",
|
|
91
|
+
6: "\xC9chec de la livraison",
|
|
92
|
+
7: "Exception",
|
|
93
|
+
8: "Enregistr\xE9"
|
|
94
|
+
},
|
|
95
|
+
it: {
|
|
96
|
+
0: "Consegnato",
|
|
97
|
+
1: "Congelato",
|
|
98
|
+
2: "In transito",
|
|
99
|
+
3: "In attesa di ritiro",
|
|
100
|
+
4: "In consegna",
|
|
101
|
+
5: "Non trovato",
|
|
102
|
+
6: "Consegna fallita",
|
|
103
|
+
7: "Eccezione",
|
|
104
|
+
8: "Registrato"
|
|
105
|
+
},
|
|
106
|
+
es: {
|
|
107
|
+
0: "Entregado",
|
|
108
|
+
1: "Congelado",
|
|
109
|
+
2: "En tr\xE1nsito",
|
|
110
|
+
3: "Esperando recogida",
|
|
111
|
+
4: "En reparto",
|
|
112
|
+
5: "No encontrado",
|
|
113
|
+
6: "Intento de entrega fallido",
|
|
114
|
+
7: "Excepci\xF3n",
|
|
115
|
+
8: "Registrado"
|
|
116
|
+
},
|
|
117
|
+
pl: {
|
|
118
|
+
0: "Dostarczone",
|
|
119
|
+
1: "Zamro\u017Cone",
|
|
120
|
+
2: "W drodze",
|
|
121
|
+
3: "Oczekuje na odbi\xF3r",
|
|
122
|
+
4: "W dor\u0119czeniu",
|
|
123
|
+
5: "Nie znaleziono",
|
|
124
|
+
6: "Nieudana pr\xF3ba dor\u0119czenia",
|
|
125
|
+
7: "Wyj\u0105tek",
|
|
126
|
+
8: "Zarejestrowane"
|
|
127
|
+
},
|
|
128
|
+
uk: {
|
|
129
|
+
0: "\u0414\u043E\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u043E",
|
|
130
|
+
1: "\u0417\u0430\u043C\u043E\u0440\u043E\u0436\u0435\u043D\u043E",
|
|
131
|
+
2: "\u0412 \u0434\u043E\u0440\u043E\u0437\u0456",
|
|
132
|
+
3: "\u041E\u0447\u0456\u043A\u0443\u0454 \u043E\u0442\u0440\u0438\u043C\u0430\u043D\u043D\u044F",
|
|
133
|
+
4: "\u0414\u043E\u0441\u0442\u0430\u0432\u043B\u044F\u0454\u0442\u044C\u0441\u044F",
|
|
134
|
+
5: "\u041D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E",
|
|
135
|
+
6: "\u041D\u0435\u0432\u0434\u0430\u043B\u0430 \u0441\u043F\u0440\u043E\u0431\u0430 \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0438",
|
|
136
|
+
7: "\u0412\u0438\u043D\u044F\u0442\u043E\u043A",
|
|
137
|
+
8: "\u0417\u0430\u0440\u0435\u0454\u0441\u0442\u0440\u043E\u0432\u0430\u043D\u043E"
|
|
138
|
+
},
|
|
139
|
+
"zh-cn": {
|
|
140
|
+
0: "\u5DF2\u9001\u8FBE",
|
|
141
|
+
1: "\u5DF2\u51BB\u7ED3",
|
|
142
|
+
2: "\u8FD0\u8F93\u4E2D",
|
|
143
|
+
3: "\u7B49\u5F85\u53D6\u4EF6",
|
|
144
|
+
4: "\u6D3E\u9001\u4E2D",
|
|
145
|
+
5: "\u672A\u627E\u5230",
|
|
146
|
+
6: "\u6D3E\u9001\u5931\u8D25",
|
|
147
|
+
7: "\u5F02\u5E38",
|
|
148
|
+
8: "\u5DF2\u767B\u8BB0"
|
|
149
|
+
}
|
|
46
150
|
};
|
|
151
|
+
const STATUS_LABELS_DE = STATUS_LABELS.de;
|
|
152
|
+
const STATUS_LABELS_EN = STATUS_LABELS.en;
|
|
153
|
+
const SUPPORTED_LANGUAGES = Object.keys(STATUS_LABELS);
|
|
154
|
+
const FALLBACK_LANGUAGE = "en";
|
|
47
155
|
// Annotate the CommonJS export names for ESM import in node:
|
|
48
156
|
0 && (module.exports = {
|
|
157
|
+
FALLBACK_LANGUAGE,
|
|
158
|
+
STATUS_LABELS,
|
|
49
159
|
STATUS_LABELS_DE,
|
|
50
|
-
STATUS_LABELS_EN
|
|
160
|
+
STATUS_LABELS_EN,
|
|
161
|
+
SUPPORTED_LANGUAGES
|
|
51
162
|
});
|
|
52
163
|
//# sourceMappingURL=types.js.map
|
package/build/lib/types.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/types.ts"],
|
|
4
|
-
"sourcesContent": ["/** API response from parcel.app deliveries endpoint */\nexport interface ParcelApiResponse {\n /** Whether the request was successful */\n success: boolean;\n /** Error message if request failed */\n error_message?: string;\n /** Error code if request failed */\n error_code?: string;\n /** List of deliveries */\n deliveries?: ParcelDelivery[];\n}\n\n/** Single delivery from the parcel.app API */\nexport interface ParcelDelivery {\n /** Carrier identifier */\n carrier_code: string;\n /** User-defined description */\n description: string;\n /** Status code (0-8 as string) */\n status_code: string;\n /** Tracking number */\n tracking_number: string;\n /** Extra info (postal code, email) */\n extra_information?: string;\n /** Expected delivery date */\n date_expected?: string;\n /** Expected delivery date end */\n date_expected_end?: string;\n /** Expected delivery Unix timestamp */\n timestamp_expected?: number;\n /** Expected delivery end Unix timestamp */\n timestamp_expected_end?: number;\n /** Tracking events (newest first) */\n events?: ParcelEvent[];\n}\n\n/** Single tracking event */\nexport interface ParcelEvent {\n /** Event description */\n event: string;\n /** Event date string */\n date: string;\n /** Event location */\n location?: string;\n /** Additional details */\n additional?: string;\n}\n\n/** Request body for adding a delivery */\nexport interface AddDeliveryRequest {\n /** Tracking number to add */\n tracking_number: string;\n /** Carrier code */\n carrier_code: string;\n /** User description */\n description: string;\n /** Tracking language */\n language?: string;\n /** Send push confirmation */\n send_push_confirmation?: boolean;\n}\n\n/** Add delivery API response */\nexport interface AddDeliveryResponse {\n /** Whether the delivery was added */\n success: boolean;\n /** Error message if failed */\n error_message?: string;\n}\n\n/** Carrier names mapping (carrier_code \u2192 display name) */\nexport type CarrierMap = Record<string, string>;\n\n/** Delivery status codes
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0EO,MAAM,
|
|
4
|
+
"sourcesContent": ["/** API response from parcel.app deliveries endpoint */\nexport interface ParcelApiResponse {\n /** Whether the request was successful */\n success: boolean;\n /** Error message if request failed */\n error_message?: string;\n /** Error code if request failed */\n error_code?: string;\n /** List of deliveries */\n deliveries?: ParcelDelivery[];\n}\n\n/** Single delivery from the parcel.app API */\nexport interface ParcelDelivery {\n /** Carrier identifier */\n carrier_code: string;\n /** User-defined description */\n description: string;\n /** Status code (0-8 as string) */\n status_code: string;\n /** Tracking number */\n tracking_number: string;\n /** Extra info (postal code, email) */\n extra_information?: string;\n /** Expected delivery date */\n date_expected?: string;\n /** Expected delivery date end */\n date_expected_end?: string;\n /** Expected delivery Unix timestamp */\n timestamp_expected?: number;\n /** Expected delivery end Unix timestamp */\n timestamp_expected_end?: number;\n /** Tracking events (newest first) */\n events?: ParcelEvent[];\n}\n\n/** Single tracking event */\nexport interface ParcelEvent {\n /** Event description */\n event: string;\n /** Event date string */\n date: string;\n /** Event location */\n location?: string;\n /** Additional details */\n additional?: string;\n}\n\n/** Request body for adding a delivery */\nexport interface AddDeliveryRequest {\n /** Tracking number to add */\n tracking_number: string;\n /** Carrier code */\n carrier_code: string;\n /** User description */\n description: string;\n /** Tracking language */\n language?: string;\n /** Send push confirmation */\n send_push_confirmation?: boolean;\n}\n\n/** Add delivery API response */\nexport interface AddDeliveryResponse {\n /** Whether the delivery was added */\n success: boolean;\n /** Error message if failed */\n error_message?: string;\n}\n\n/** Carrier names mapping (carrier_code \u2192 display name) */\nexport type CarrierMap = Record<string, string>;\n\n/** Delivery status labels for status codes 0-8, keyed by ioBroker language code */\nexport const STATUS_LABELS: Record<string, Record<number, string>> = {\n de: {\n 0: \"Zugestellt\",\n 1: \"Eingefroren\",\n 2: \"Unterwegs\",\n 3: \"Abholung erwartet\",\n 4: \"In Zustellung\",\n 5: \"Nicht gefunden\",\n 6: \"Zustellversuch gescheitert\",\n 7: \"Ausnahme\",\n 8: \"Registriert\",\n },\n en: {\n 0: \"Delivered\",\n 1: \"Frozen\",\n 2: \"In Transit\",\n 3: \"Awaiting Pickup\",\n 4: \"Out for Delivery\",\n 5: \"Not Found\",\n 6: \"Delivery Attempt Failed\",\n 7: \"Exception\",\n 8: \"Info Received\",\n },\n ru: {\n 0: \"\u0414\u043E\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u043E\",\n 1: \"\u0417\u0430\u043C\u043E\u0440\u043E\u0436\u0435\u043D\u043E\",\n 2: \"\u0412 \u043F\u0443\u0442\u0438\",\n 3: \"\u041E\u0436\u0438\u0434\u0430\u0435\u0442 \u043F\u043E\u043B\u0443\u0447\u0435\u043D\u0438\u044F\",\n 4: \"\u0414\u043E\u0441\u0442\u0430\u0432\u043B\u044F\u0435\u0442\u0441\u044F\",\n 5: \"\u041D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E\",\n 6: \"\u041D\u0435\u0443\u0434\u0430\u0447\u043D\u0430\u044F \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0430\",\n 7: \"\u0418\u0441\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435\",\n 8: \"\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u043E\",\n },\n pt: {\n 0: \"Entregue\",\n 1: \"Congelado\",\n 2: \"Em tr\u00E2nsito\",\n 3: \"Aguardando recolha\",\n 4: \"Em entrega\",\n 5: \"N\u00E3o encontrado\",\n 6: \"Tentativa de entrega falhou\",\n 7: \"Exce\u00E7\u00E3o\",\n 8: \"Registado\",\n },\n nl: {\n 0: \"Bezorgd\",\n 1: \"Bevroren\",\n 2: \"Onderweg\",\n 3: \"Wacht op ophaling\",\n 4: \"Wordt bezorgd\",\n 5: \"Niet gevonden\",\n 6: \"Bezorgpoging mislukt\",\n 7: \"Uitzondering\",\n 8: \"Geregistreerd\",\n },\n fr: {\n 0: \"Livr\u00E9\",\n 1: \"Gel\u00E9\",\n 2: \"En transit\",\n 3: \"En attente de retrait\",\n 4: \"En cours de livraison\",\n 5: \"Introuvable\",\n 6: \"\u00C9chec de la livraison\",\n 7: \"Exception\",\n 8: \"Enregistr\u00E9\",\n },\n it: {\n 0: \"Consegnato\",\n 1: \"Congelato\",\n 2: \"In transito\",\n 3: \"In attesa di ritiro\",\n 4: \"In consegna\",\n 5: \"Non trovato\",\n 6: \"Consegna fallita\",\n 7: \"Eccezione\",\n 8: \"Registrato\",\n },\n es: {\n 0: \"Entregado\",\n 1: \"Congelado\",\n 2: \"En tr\u00E1nsito\",\n 3: \"Esperando recogida\",\n 4: \"En reparto\",\n 5: \"No encontrado\",\n 6: \"Intento de entrega fallido\",\n 7: \"Excepci\u00F3n\",\n 8: \"Registrado\",\n },\n pl: {\n 0: \"Dostarczone\",\n 1: \"Zamro\u017Cone\",\n 2: \"W drodze\",\n 3: \"Oczekuje na odbi\u00F3r\",\n 4: \"W dor\u0119czeniu\",\n 5: \"Nie znaleziono\",\n 6: \"Nieudana pr\u00F3ba dor\u0119czenia\",\n 7: \"Wyj\u0105tek\",\n 8: \"Zarejestrowane\",\n },\n uk: {\n 0: \"\u0414\u043E\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u043E\",\n 1: \"\u0417\u0430\u043C\u043E\u0440\u043E\u0436\u0435\u043D\u043E\",\n 2: \"\u0412 \u0434\u043E\u0440\u043E\u0437\u0456\",\n 3: \"\u041E\u0447\u0456\u043A\u0443\u0454 \u043E\u0442\u0440\u0438\u043C\u0430\u043D\u043D\u044F\",\n 4: \"\u0414\u043E\u0441\u0442\u0430\u0432\u043B\u044F\u0454\u0442\u044C\u0441\u044F\",\n 5: \"\u041D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u043E\",\n 6: \"\u041D\u0435\u0432\u0434\u0430\u043B\u0430 \u0441\u043F\u0440\u043E\u0431\u0430 \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u0438\",\n 7: \"\u0412\u0438\u043D\u044F\u0442\u043E\u043A\",\n 8: \"\u0417\u0430\u0440\u0435\u0454\u0441\u0442\u0440\u043E\u0432\u0430\u043D\u043E\",\n },\n \"zh-cn\": {\n 0: \"\u5DF2\u9001\u8FBE\",\n 1: \"\u5DF2\u51BB\u7ED3\",\n 2: \"\u8FD0\u8F93\u4E2D\",\n 3: \"\u7B49\u5F85\u53D6\u4EF6\",\n 4: \"\u6D3E\u9001\u4E2D\",\n 5: \"\u672A\u627E\u5230\",\n 6: \"\u6D3E\u9001\u5931\u8D25\",\n 7: \"\u5F02\u5E38\",\n 8: \"\u5DF2\u767B\u8BB0\",\n },\n};\n\n/** Backward-compatible aliases (used by tests and legacy imports) */\nexport const STATUS_LABELS_DE = STATUS_LABELS.de;\nexport const STATUS_LABELS_EN = STATUS_LABELS.en;\n\n/** Language codes the adapter generates state labels for */\nexport const SUPPORTED_LANGUAGES = Object.keys(STATUS_LABELS);\n\n/** Fallback language used when system.config.language is outside SUPPORTED_LANGUAGES */\nexport const FALLBACK_LANGUAGE = \"en\";\n\n// Augment the ioBroker global namespace\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace ioBroker {\n interface AdapterConfig {\n /** parcel.app API key */\n apiKey: string;\n /** Polling interval in minutes */\n pollInterval: number;\n /** Automatically remove delivered packages from states */\n autoRemoveDelivered: boolean;\n }\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0EO,MAAM,gBAAwD;AAAA,EACnE,IAAI;AAAA,IACF,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AAAA,EACA,IAAI;AAAA,IACF,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AAAA,EACA,IAAI;AAAA,IACF,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AAAA,EACA,IAAI;AAAA,IACF,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AAAA,EACA,IAAI;AAAA,IACF,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AAAA,EACA,IAAI;AAAA,IACF,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AAAA,EACA,IAAI;AAAA,IACF,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AAAA,EACA,IAAI;AAAA,IACF,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AAAA,EACA,IAAI;AAAA,IACF,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AAAA,EACA,IAAI;AAAA,IACF,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AAAA,EACA,SAAS;AAAA,IACP,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AACF;AAGO,MAAM,mBAAmB,cAAc;AACvC,MAAM,mBAAmB,cAAc;AAGvC,MAAM,sBAAsB,OAAO,KAAK,aAAa;AAGrD,MAAM,oBAAoB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/build/main.js
CHANGED
|
@@ -28,6 +28,9 @@ const MIN_POLL_INTERVAL = 5;
|
|
|
28
28
|
const MAX_POLL_INTERVAL = 60;
|
|
29
29
|
const DEFAULT_POLL_INTERVAL = 10;
|
|
30
30
|
const MIN_POLL_GAP_MS = 6e4;
|
|
31
|
+
function errText(err) {
|
|
32
|
+
return err instanceof Error ? err.message : String(err);
|
|
33
|
+
}
|
|
31
34
|
class ParcelappAdapter extends utils.Adapter {
|
|
32
35
|
client = null;
|
|
33
36
|
stateManager = null;
|
|
@@ -37,18 +40,36 @@ class ParcelappAdapter extends utils.Adapter {
|
|
|
37
40
|
rateLimitedUntil = 0;
|
|
38
41
|
lastErrorCode = "";
|
|
39
42
|
failedDeliveries = /* @__PURE__ */ new Set();
|
|
43
|
+
unhandledRejectionHandler = null;
|
|
44
|
+
uncaughtExceptionHandler = null;
|
|
40
45
|
/** @param options Adapter options */
|
|
41
46
|
constructor(options = {}) {
|
|
42
47
|
super({
|
|
43
48
|
...options,
|
|
44
49
|
name: "parcelapp"
|
|
45
50
|
});
|
|
46
|
-
this.on("ready",
|
|
51
|
+
this.on("ready", () => {
|
|
52
|
+
this.onReady().catch(
|
|
53
|
+
(err) => this.log.error(`onReady failed: ${errText(err)}`)
|
|
54
|
+
);
|
|
55
|
+
});
|
|
47
56
|
this.on("unload", this.onUnload.bind(this));
|
|
48
|
-
this.on("message",
|
|
57
|
+
this.on("message", (obj) => {
|
|
58
|
+
this.onMessage(obj).catch(
|
|
59
|
+
(err) => this.log.error(`onMessage failed: ${errText(err)}`)
|
|
60
|
+
);
|
|
61
|
+
});
|
|
62
|
+
this.unhandledRejectionHandler = (reason) => {
|
|
63
|
+
this.log.error(`Unhandled rejection: ${errText(reason)}`);
|
|
64
|
+
};
|
|
65
|
+
this.uncaughtExceptionHandler = (err) => {
|
|
66
|
+
this.log.error(`Uncaught exception: ${errText(err)}`);
|
|
67
|
+
};
|
|
68
|
+
process.on("unhandledRejection", this.unhandledRejectionHandler);
|
|
69
|
+
process.on("uncaughtException", this.uncaughtExceptionHandler);
|
|
49
70
|
}
|
|
50
71
|
async onReady() {
|
|
51
|
-
var _a;
|
|
72
|
+
var _a, _b, _c;
|
|
52
73
|
await this.setStateAsync("info.connection", { val: false, ack: true });
|
|
53
74
|
const { apiKey } = this.config;
|
|
54
75
|
if (!apiKey || apiKey.trim().length < 10) {
|
|
@@ -57,15 +78,17 @@ class ParcelappAdapter extends utils.Adapter {
|
|
|
57
78
|
);
|
|
58
79
|
return;
|
|
59
80
|
}
|
|
81
|
+
const sysConfig = await this.getForeignObjectAsync("system.config");
|
|
82
|
+
const language = (_b = (_a = sysConfig == null ? void 0 : sysConfig.common) == null ? void 0 : _a.language) != null ? _b : "";
|
|
60
83
|
this.client = new import_parcel_client.ParcelClient(apiKey.trim());
|
|
61
|
-
this.stateManager = new import_state_manager.StateManager(this);
|
|
84
|
+
this.stateManager = new import_state_manager.StateManager(this, language);
|
|
62
85
|
await this.cleanupObsoleteStates();
|
|
63
86
|
await this.poll();
|
|
64
87
|
const interval = Math.max(
|
|
65
88
|
MIN_POLL_INTERVAL,
|
|
66
89
|
Math.min(
|
|
67
90
|
MAX_POLL_INTERVAL,
|
|
68
|
-
(
|
|
91
|
+
(_c = this.config.pollInterval) != null ? _c : DEFAULT_POLL_INTERVAL
|
|
69
92
|
)
|
|
70
93
|
);
|
|
71
94
|
const intervalMs = interval * 60 * 1e3;
|
|
@@ -80,6 +103,14 @@ class ParcelappAdapter extends utils.Adapter {
|
|
|
80
103
|
this.clearInterval(this.pollTimer);
|
|
81
104
|
this.pollTimer = void 0;
|
|
82
105
|
}
|
|
106
|
+
if (this.unhandledRejectionHandler) {
|
|
107
|
+
process.off("unhandledRejection", this.unhandledRejectionHandler);
|
|
108
|
+
this.unhandledRejectionHandler = null;
|
|
109
|
+
}
|
|
110
|
+
if (this.uncaughtExceptionHandler) {
|
|
111
|
+
process.off("uncaughtException", this.uncaughtExceptionHandler);
|
|
112
|
+
this.uncaughtExceptionHandler = null;
|
|
113
|
+
}
|
|
83
114
|
void this.setState("info.connection", { val: false, ack: true });
|
|
84
115
|
} catch {
|
|
85
116
|
}
|
package/build/main.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/main.ts"],
|
|
4
|
-
"sourcesContent": ["import * as utils from \"@iobroker/adapter-core\";\nimport { ParcelClient } from \"./lib/parcel-client\";\nimport { StateManager } from \"./lib/state-manager\";\n\nconst MIN_POLL_INTERVAL = 5;\nconst MAX_POLL_INTERVAL = 60;\nconst DEFAULT_POLL_INTERVAL = 10;\nconst MIN_POLL_GAP_MS = 60_000; // Minimum 60s between polls\n\n/** ioBroker adapter for parcel.app package tracking */\nclass ParcelappAdapter extends utils.Adapter {\n private client: ParcelClient | null = null;\n private stateManager: StateManager | null = null;\n private pollTimer: ioBroker.Interval | undefined = undefined;\n private isPolling = false;\n private lastPollTime = 0;\n private rateLimitedUntil = 0;\n private lastErrorCode = \"\";\n private failedDeliveries = new Set<string>();\n\n /** @param options Adapter options */\n public constructor(options: Partial<utils.AdapterOptions> = {}) {\n super({\n ...options,\n name: \"parcelapp\",\n });\n this.on(\"ready\", this.onReady.bind(this));\n this.on(\"unload\", this.onUnload.bind(this));\n this.on(\"message\", this.onMessage.bind(this));\n }\n\n private async onReady(): Promise<void> {\n await this.setStateAsync(\"info.connection\", { val: false, ack: true });\n\n // Validate config\n const { apiKey } = this.config;\n if (!apiKey || apiKey.trim().length < 10) {\n this.log.error(\n \"No valid API key configured \u2014 please enter your parcel.app API key in the adapter settings\",\n );\n return;\n }\n\n // Initialize\n this.client = new ParcelClient(apiKey.trim());\n this.stateManager = new StateManager(this);\n\n // Cleanup obsolete states\n await this.cleanupObsoleteStates();\n\n // Initial poll\n await this.poll();\n\n // Set up recurring poll\n const interval = Math.max(\n MIN_POLL_INTERVAL,\n Math.min(\n MAX_POLL_INTERVAL,\n this.config.pollInterval ?? DEFAULT_POLL_INTERVAL,\n ),\n );\n const intervalMs = interval * 60 * 1000;\n this.pollTimer = this.setInterval(() => void this.poll(), intervalMs);\n\n this.log.info(\n `Parcel tracking started \u2014 polling every ${interval} minutes`,\n );\n }\n\n private onUnload(callback: () => void): void {\n try {\n if (this.pollTimer) {\n this.clearInterval(this.pollTimer);\n this.pollTimer = undefined;\n }\n void this.setState(\"info.connection\", { val: false, ack: true });\n } catch {\n // ignore\n }\n callback();\n }\n\n private async onMessage(obj: ioBroker.Message): Promise<void> {\n if (!obj?.command || !obj.callback) {\n return;\n }\n\n try {\n switch (obj.command) {\n case \"checkConnection\": {\n const msg = obj.message as { apiKey?: string };\n const key = msg?.apiKey?.trim() || \"\";\n if (!key || key.length < 10) {\n this.sendTo(\n obj.from,\n obj.command,\n { success: false, message: \"API key is too short\" },\n obj.callback,\n );\n return;\n }\n const testClient = new ParcelClient(key);\n const result = await testClient.testConnection();\n this.sendTo(obj.from, obj.command, result, obj.callback);\n break;\n }\n case \"addDelivery\": {\n if (!this.client) {\n this.sendTo(\n obj.from,\n obj.command,\n { success: false, error_message: \"Adapter not initialized\" },\n obj.callback,\n );\n return;\n }\n const request = obj.message as {\n tracking_number: string;\n carrier_code: string;\n description: string;\n };\n const addResult = await this.client.addDelivery(request);\n this.sendTo(obj.from, obj.command, addResult, obj.callback);\n if (addResult.success) {\n void this.poll();\n }\n break;\n }\n default:\n this.sendTo(\n obj.from,\n obj.command,\n { error: \"Unknown command\" },\n obj.callback,\n );\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.sendTo(\n obj.from,\n obj.command,\n { success: false, error_message: msg },\n obj.callback,\n );\n }\n }\n\n private async cleanupObsoleteStates(): Promise<void> {\n const obsoleteStates = [\n \"summary.json\", // removed in 0.2.0\n ];\n for (const stateId of obsoleteStates) {\n const obj = await this.getObjectAsync(stateId);\n if (obj) {\n await this.delObjectAsync(stateId);\n this.log.debug(`Removed obsolete state: ${stateId}`);\n }\n }\n }\n\n /**\n * Classify an error for deduplication and log-level decisions.\n *\n * @param error The error to classify\n */\n private classifyError(error: Error & { code?: string }): string {\n if (error.code === \"RATE_LIMITED\") {\n return \"RATE_LIMITED\";\n }\n if (error.code === \"INVALID_API_KEY\") {\n return \"INVALID_API_KEY\";\n }\n // Network errors: DNS, connection refused, no internet\n if (\n error.code === \"ENOTFOUND\" ||\n error.code === \"ECONNREFUSED\" ||\n error.code === \"ECONNRESET\" ||\n error.code === \"ENETUNREACH\" ||\n error.code === \"EHOSTUNREACH\" ||\n error.code === \"EAI_AGAIN\"\n ) {\n return \"NETWORK\";\n }\n if (error.message.includes(\"timeout\") || error.code === \"ETIMEDOUT\") {\n return \"TIMEOUT\";\n }\n return error.code || \"UNKNOWN\";\n }\n\n private async poll(): Promise<void> {\n if (this.isPolling || !this.client || !this.stateManager) {\n return;\n }\n\n const now = Date.now();\n\n // Skip if rate limited\n if (now < this.rateLimitedUntil) {\n const waitMin = Math.ceil((this.rateLimitedUntil - now) / 60_000);\n this.log.debug(\n `Skipping poll \u2014 rate limited for ${waitMin} more minute(s)`,\n );\n return;\n }\n\n // Throttle: minimum gap between polls\n if (now - this.lastPollTime < MIN_POLL_GAP_MS) {\n this.log.debug(\"Skipping poll \u2014 too soon after last poll\");\n return;\n }\n\n this.isPolling = true;\n this.lastPollTime = now;\n try {\n // When keeping delivered packages, use \"recent\" to get them from API\n const autoRemove = this.config.autoRemoveDelivered !== false;\n const deliveries = await this.client.getDeliveries(\n autoRemove ? \"active\" : \"recent\",\n );\n\n // Reset error state on success\n this.rateLimitedUntil = 0;\n if (this.lastErrorCode) {\n this.log.info(\"Connection restored\");\n this.lastErrorCode = \"\";\n }\n await this.setStateAsync(\"info.connection\", { val: true, ack: true });\n\n // Split into active (non-delivered) and visible (what gets states)\n const activeDeliveries = deliveries.filter(\n (d) => this.stateManager!.parseStatus(d) !== 0,\n );\n const visibleDeliveries = autoRemove ? activeDeliveries : deliveries;\n\n // Update each delivery (isolated: one failure must not block others)\n const activeIds: string[] = [];\n for (const delivery of visibleDeliveries) {\n try {\n const carrierName = await this.client.getCarrierName(\n delivery.carrier_code,\n );\n await this.stateManager.updateDelivery(delivery, carrierName);\n activeIds.push(this.stateManager.packageId(delivery));\n this.failedDeliveries.delete(delivery.tracking_number);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (this.failedDeliveries.has(delivery.tracking_number)) {\n this.log.debug(\n `Failed to update \"${delivery.tracking_number}\": ${msg}`,\n );\n } else {\n this.log.warn(\n `Failed to update \"${delivery.tracking_number}\": ${msg}`,\n );\n this.failedDeliveries.add(delivery.tracking_number);\n }\n }\n }\n\n // Cleanup stale deliveries\n await this.stateManager.cleanupDeliveries(activeIds);\n\n // Update summary (always uses active/non-delivered)\n await this.stateManager.updateSummary(activeDeliveries);\n\n this.log.debug(\n `Polled ${visibleDeliveries.length} deliveries (${activeDeliveries.length} active)`,\n );\n } catch (err) {\n const error = err as Error & {\n code?: string;\n retryAfterSeconds?: number;\n };\n\n // Classify the error\n const errorCode = this.classifyError(error);\n const isRepeat = errorCode === this.lastErrorCode;\n this.lastErrorCode = errorCode;\n\n if (error.code === \"RATE_LIMITED\") {\n const cooldownSec = error.retryAfterSeconds || 5 * 60;\n this.rateLimitedUntil = Date.now() + cooldownSec * 1000;\n this.log.warn(\n `Rate limit hit \u2014 pausing API requests for ${Math.ceil(cooldownSec / 60)} minute(s)`,\n );\n } else if (error.code === \"INVALID_API_KEY\") {\n // Always log \u2014 user must fix config\n this.log.error(\n \"Invalid API key \u2014 please check your parcel.app API key\",\n );\n } else if (isRepeat) {\n // Same error as last time \u2014 don't spam the log\n this.log.debug(`Poll failed (ongoing): ${error.message}`);\n } else if (errorCode === \"NETWORK\") {\n this.log.warn(`Cannot reach parcel.app API \u2014 will keep retrying`);\n } else if (errorCode === \"TIMEOUT\") {\n this.log.warn(`API request timeout \u2014 will retry next cycle`);\n } else {\n this.log.error(`Poll failed: ${error.message}`);\n }\n\n await this.setStateAsync(\"info.connection\", { val: false, ack: true });\n } finally {\n this.isPolling = false;\n }\n }\n}\n\nif (require.main !== module) {\n module.exports = (options: Partial<utils.AdapterOptions> | undefined) =>\n new ParcelappAdapter(options);\n} else {\n (() => new ParcelappAdapter())();\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA,YAAuB;AACvB,2BAA6B;AAC7B,2BAA6B;AAE7B,MAAM,oBAAoB;AAC1B,MAAM,oBAAoB;AAC1B,MAAM,wBAAwB;AAC9B,MAAM,kBAAkB;
|
|
4
|
+
"sourcesContent": ["import * as utils from \"@iobroker/adapter-core\";\nimport { ParcelClient } from \"./lib/parcel-client\";\nimport { StateManager } from \"./lib/state-manager\";\n\nconst MIN_POLL_INTERVAL = 5;\nconst MAX_POLL_INTERVAL = 60;\nconst DEFAULT_POLL_INTERVAL = 10;\nconst MIN_POLL_GAP_MS = 60_000; // Minimum 60s between polls\n\n/**\n * Extract a log-friendly message from an unknown error value.\n *\n * @param err Value caught in a promise rejection (may or may not be an Error)\n */\nfunction errText(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\n/** ioBroker adapter for parcel.app package tracking */\nclass ParcelappAdapter extends utils.Adapter {\n private client: ParcelClient | null = null;\n private stateManager: StateManager | null = null;\n private pollTimer: ioBroker.Interval | undefined = undefined;\n private isPolling = false;\n private lastPollTime = 0;\n private rateLimitedUntil = 0;\n private lastErrorCode = \"\";\n private failedDeliveries = new Set<string>();\n private unhandledRejectionHandler: ((reason: unknown) => void) | null = null;\n private uncaughtExceptionHandler: ((err: Error) => void) | null = null;\n\n /** @param options Adapter options */\n public constructor(options: Partial<utils.AdapterOptions> = {}) {\n super({\n ...options,\n name: \"parcelapp\",\n });\n // Wrap async handlers with .catch() so a rejection can never become an\n // unhandled promise rejection (which would SIGKILL the adapter and trap\n // js-controller in a restart loop without any stack trace).\n this.on(\"ready\", () => {\n this.onReady().catch((err) =>\n this.log.error(`onReady failed: ${errText(err)}`),\n );\n });\n this.on(\"unload\", this.onUnload.bind(this));\n this.on(\"message\", (obj) => {\n this.onMessage(obj).catch((err) =>\n this.log.error(`onMessage failed: ${errText(err)}`),\n );\n });\n // Last-line-of-defence against unhandled rejections / sync throws from\n // fire-and-forget paths (e.g. `void this.poll()`). The per-handler\n // .catch() wrappers cover the documented async paths; this catches\n // anything that slips past during refactors.\n this.unhandledRejectionHandler = (reason: unknown) => {\n this.log.error(`Unhandled rejection: ${errText(reason)}`);\n };\n this.uncaughtExceptionHandler = (err: Error) => {\n this.log.error(`Uncaught exception: ${errText(err)}`);\n };\n process.on(\"unhandledRejection\", this.unhandledRejectionHandler);\n process.on(\"uncaughtException\", this.uncaughtExceptionHandler);\n }\n\n private async onReady(): Promise<void> {\n await this.setStateAsync(\"info.connection\", { val: false, ack: true });\n\n // Validate config\n const { apiKey } = this.config;\n if (!apiKey || apiKey.trim().length < 10) {\n this.log.error(\n \"No valid API key configured \u2014 please enter your parcel.app API key in the adapter settings\",\n );\n return;\n }\n\n // Pick the label language from the ioBroker system configuration.\n // StateManager falls back to English if the language is unsupported.\n const sysConfig = await this.getForeignObjectAsync(\"system.config\");\n const language =\n (sysConfig?.common as { language?: string } | undefined)?.language ?? \"\";\n\n // Initialize\n this.client = new ParcelClient(apiKey.trim());\n this.stateManager = new StateManager(this, language);\n\n // Cleanup obsolete states\n await this.cleanupObsoleteStates();\n\n // Initial poll\n await this.poll();\n\n // Set up recurring poll\n const interval = Math.max(\n MIN_POLL_INTERVAL,\n Math.min(\n MAX_POLL_INTERVAL,\n this.config.pollInterval ?? DEFAULT_POLL_INTERVAL,\n ),\n );\n const intervalMs = interval * 60 * 1000;\n this.pollTimer = this.setInterval(() => void this.poll(), intervalMs);\n\n this.log.info(\n `Parcel tracking started \u2014 polling every ${interval} minutes`,\n );\n }\n\n private onUnload(callback: () => void): void {\n try {\n if (this.pollTimer) {\n this.clearInterval(this.pollTimer);\n this.pollTimer = undefined;\n }\n if (this.unhandledRejectionHandler) {\n process.off(\"unhandledRejection\", this.unhandledRejectionHandler);\n this.unhandledRejectionHandler = null;\n }\n if (this.uncaughtExceptionHandler) {\n process.off(\"uncaughtException\", this.uncaughtExceptionHandler);\n this.uncaughtExceptionHandler = null;\n }\n void this.setState(\"info.connection\", { val: false, ack: true });\n } catch {\n // ignore\n }\n callback();\n }\n\n private async onMessage(obj: ioBroker.Message): Promise<void> {\n if (!obj?.command || !obj.callback) {\n return;\n }\n\n try {\n switch (obj.command) {\n case \"checkConnection\": {\n const msg = obj.message as { apiKey?: string };\n const key = msg?.apiKey?.trim() || \"\";\n if (!key || key.length < 10) {\n this.sendTo(\n obj.from,\n obj.command,\n { success: false, message: \"API key is too short\" },\n obj.callback,\n );\n return;\n }\n const testClient = new ParcelClient(key);\n const result = await testClient.testConnection();\n this.sendTo(obj.from, obj.command, result, obj.callback);\n break;\n }\n case \"addDelivery\": {\n if (!this.client) {\n this.sendTo(\n obj.from,\n obj.command,\n { success: false, error_message: \"Adapter not initialized\" },\n obj.callback,\n );\n return;\n }\n const request = obj.message as {\n tracking_number: string;\n carrier_code: string;\n description: string;\n };\n const addResult = await this.client.addDelivery(request);\n this.sendTo(obj.from, obj.command, addResult, obj.callback);\n if (addResult.success) {\n void this.poll();\n }\n break;\n }\n default:\n this.sendTo(\n obj.from,\n obj.command,\n { error: \"Unknown command\" },\n obj.callback,\n );\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.sendTo(\n obj.from,\n obj.command,\n { success: false, error_message: msg },\n obj.callback,\n );\n }\n }\n\n private async cleanupObsoleteStates(): Promise<void> {\n const obsoleteStates = [\n \"summary.json\", // removed in 0.2.0\n ];\n for (const stateId of obsoleteStates) {\n const obj = await this.getObjectAsync(stateId);\n if (obj) {\n await this.delObjectAsync(stateId);\n this.log.debug(`Removed obsolete state: ${stateId}`);\n }\n }\n }\n\n /**\n * Classify an error for deduplication and log-level decisions.\n *\n * @param error The error to classify\n */\n private classifyError(error: Error & { code?: string }): string {\n if (error.code === \"RATE_LIMITED\") {\n return \"RATE_LIMITED\";\n }\n if (error.code === \"INVALID_API_KEY\") {\n return \"INVALID_API_KEY\";\n }\n // Network errors: DNS, connection refused, no internet\n if (\n error.code === \"ENOTFOUND\" ||\n error.code === \"ECONNREFUSED\" ||\n error.code === \"ECONNRESET\" ||\n error.code === \"ENETUNREACH\" ||\n error.code === \"EHOSTUNREACH\" ||\n error.code === \"EAI_AGAIN\"\n ) {\n return \"NETWORK\";\n }\n if (error.message.includes(\"timeout\") || error.code === \"ETIMEDOUT\") {\n return \"TIMEOUT\";\n }\n return error.code || \"UNKNOWN\";\n }\n\n private async poll(): Promise<void> {\n if (this.isPolling || !this.client || !this.stateManager) {\n return;\n }\n\n const now = Date.now();\n\n // Skip if rate limited\n if (now < this.rateLimitedUntil) {\n const waitMin = Math.ceil((this.rateLimitedUntil - now) / 60_000);\n this.log.debug(\n `Skipping poll \u2014 rate limited for ${waitMin} more minute(s)`,\n );\n return;\n }\n\n // Throttle: minimum gap between polls\n if (now - this.lastPollTime < MIN_POLL_GAP_MS) {\n this.log.debug(\"Skipping poll \u2014 too soon after last poll\");\n return;\n }\n\n this.isPolling = true;\n this.lastPollTime = now;\n try {\n // When keeping delivered packages, use \"recent\" to get them from API\n const autoRemove = this.config.autoRemoveDelivered !== false;\n const deliveries = await this.client.getDeliveries(\n autoRemove ? \"active\" : \"recent\",\n );\n\n // Reset error state on success\n this.rateLimitedUntil = 0;\n if (this.lastErrorCode) {\n this.log.info(\"Connection restored\");\n this.lastErrorCode = \"\";\n }\n await this.setStateAsync(\"info.connection\", { val: true, ack: true });\n\n // Split into active (non-delivered) and visible (what gets states)\n const activeDeliveries = deliveries.filter(\n (d) => this.stateManager!.parseStatus(d) !== 0,\n );\n const visibleDeliveries = autoRemove ? activeDeliveries : deliveries;\n\n // Update each delivery (isolated: one failure must not block others)\n const activeIds: string[] = [];\n for (const delivery of visibleDeliveries) {\n try {\n const carrierName = await this.client.getCarrierName(\n delivery.carrier_code,\n );\n await this.stateManager.updateDelivery(delivery, carrierName);\n activeIds.push(this.stateManager.packageId(delivery));\n this.failedDeliveries.delete(delivery.tracking_number);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (this.failedDeliveries.has(delivery.tracking_number)) {\n this.log.debug(\n `Failed to update \"${delivery.tracking_number}\": ${msg}`,\n );\n } else {\n this.log.warn(\n `Failed to update \"${delivery.tracking_number}\": ${msg}`,\n );\n this.failedDeliveries.add(delivery.tracking_number);\n }\n }\n }\n\n // Cleanup stale deliveries\n await this.stateManager.cleanupDeliveries(activeIds);\n\n // Update summary (always uses active/non-delivered)\n await this.stateManager.updateSummary(activeDeliveries);\n\n this.log.debug(\n `Polled ${visibleDeliveries.length} deliveries (${activeDeliveries.length} active)`,\n );\n } catch (err) {\n const error = err as Error & {\n code?: string;\n retryAfterSeconds?: number;\n };\n\n // Classify the error\n const errorCode = this.classifyError(error);\n const isRepeat = errorCode === this.lastErrorCode;\n this.lastErrorCode = errorCode;\n\n if (error.code === \"RATE_LIMITED\") {\n const cooldownSec = error.retryAfterSeconds || 5 * 60;\n this.rateLimitedUntil = Date.now() + cooldownSec * 1000;\n this.log.warn(\n `Rate limit hit \u2014 pausing API requests for ${Math.ceil(cooldownSec / 60)} minute(s)`,\n );\n } else if (error.code === \"INVALID_API_KEY\") {\n // Always log \u2014 user must fix config\n this.log.error(\n \"Invalid API key \u2014 please check your parcel.app API key\",\n );\n } else if (isRepeat) {\n // Same error as last time \u2014 don't spam the log\n this.log.debug(`Poll failed (ongoing): ${error.message}`);\n } else if (errorCode === \"NETWORK\") {\n this.log.warn(`Cannot reach parcel.app API \u2014 will keep retrying`);\n } else if (errorCode === \"TIMEOUT\") {\n this.log.warn(`API request timeout \u2014 will retry next cycle`);\n } else {\n this.log.error(`Poll failed: ${error.message}`);\n }\n\n await this.setStateAsync(\"info.connection\", { val: false, ack: true });\n } finally {\n this.isPolling = false;\n }\n }\n}\n\nif (require.main !== module) {\n module.exports = (options: Partial<utils.AdapterOptions> | undefined) =>\n new ParcelappAdapter(options);\n} else {\n (() => new ParcelappAdapter())();\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|