node-chargepoint 0.3.3 → 0.3.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/dist/cli.cjs +97 -12
- package/dist/index.cjs +30 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +30 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -26,9 +26,80 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
// src/cli.ts
|
|
27
27
|
var import_commander = require("commander");
|
|
28
28
|
|
|
29
|
+
// package.json
|
|
30
|
+
var package_default = {
|
|
31
|
+
name: "node-chargepoint",
|
|
32
|
+
version: "0.3.5",
|
|
33
|
+
description: "A Node.js/TypeScript wrapper for the ChargePoint EV charging network API. Based on python-chargepoint by Marc Billow.",
|
|
34
|
+
keywords: [
|
|
35
|
+
"chargepoint",
|
|
36
|
+
"ev",
|
|
37
|
+
"electric-vehicle",
|
|
38
|
+
"charging",
|
|
39
|
+
"evse"
|
|
40
|
+
],
|
|
41
|
+
homepage: "https://github.com/musicbender/node-chargepoint",
|
|
42
|
+
repository: {
|
|
43
|
+
type: "git",
|
|
44
|
+
url: "git+https://github.com/musicbender/node-chargepoint.git"
|
|
45
|
+
},
|
|
46
|
+
bugs: {
|
|
47
|
+
url: "https://github.com/musicbender/node-chargepoint/issues"
|
|
48
|
+
},
|
|
49
|
+
license: "MIT",
|
|
50
|
+
type: "module",
|
|
51
|
+
main: "./dist/index.cjs",
|
|
52
|
+
module: "./dist/index.js",
|
|
53
|
+
types: "./dist/index.d.ts",
|
|
54
|
+
exports: {
|
|
55
|
+
".": {
|
|
56
|
+
import: {
|
|
57
|
+
types: "./dist/index.d.ts",
|
|
58
|
+
default: "./dist/index.js"
|
|
59
|
+
},
|
|
60
|
+
require: {
|
|
61
|
+
types: "./dist/index.d.cts",
|
|
62
|
+
default: "./dist/index.cjs"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
bin: {
|
|
67
|
+
chargepoint: "./dist/cli.cjs"
|
|
68
|
+
},
|
|
69
|
+
files: [
|
|
70
|
+
"dist",
|
|
71
|
+
"LICENSE"
|
|
72
|
+
],
|
|
73
|
+
scripts: {
|
|
74
|
+
build: "tsup",
|
|
75
|
+
typecheck: "tsc --noEmit",
|
|
76
|
+
lint: "eslint src tests",
|
|
77
|
+
test: "vitest run",
|
|
78
|
+
"test:watch": "vitest",
|
|
79
|
+
"test:e2e": "vitest run --config vitest.e2e.config.ts",
|
|
80
|
+
prepublishOnly: "pnpm build && pnpm typecheck"
|
|
81
|
+
},
|
|
82
|
+
engines: {
|
|
83
|
+
node: ">=24"
|
|
84
|
+
},
|
|
85
|
+
packageManager: "pnpm@11.0.9+sha512.34ce82e6780233cf9cad8685029a8f81d2e06196c5a9bad98879f7424940c6817c4e4524fb7d38b8553ceed48b9758b8ebaf1abd3600c232c4c8cf7366086f38",
|
|
86
|
+
dependencies: {
|
|
87
|
+
commander: "^12.1.0"
|
|
88
|
+
},
|
|
89
|
+
devDependencies: {
|
|
90
|
+
"@types/node": "^22.0.0",
|
|
91
|
+
eslint: "^10.3.0",
|
|
92
|
+
msw: "^2.7.0",
|
|
93
|
+
tsup: "^8.3.0",
|
|
94
|
+
typescript: "^5.8.0",
|
|
95
|
+
"typescript-eslint": "^8.59.2",
|
|
96
|
+
vitest: "^2.1.0"
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
29
100
|
// src/constants.ts
|
|
30
101
|
var DISCOVERY_API = "https://discovery.chargepoint.com/discovery/v3/globalconfig";
|
|
31
|
-
var VERSION =
|
|
102
|
+
var VERSION = package_default.version;
|
|
32
103
|
var USER_AGENT = `node-chargepoint/${VERSION}`;
|
|
33
104
|
|
|
34
105
|
// src/exceptions.ts
|
|
@@ -335,7 +406,12 @@ var ChargingSession = class _ChargingSession {
|
|
|
335
406
|
}
|
|
336
407
|
static async start(deviceId, client) {
|
|
337
408
|
await sendCommand(client, "start", deviceId);
|
|
338
|
-
const
|
|
409
|
+
const deadline = Date.now() + 15e3;
|
|
410
|
+
let status = await client.getUserChargingStatus();
|
|
411
|
+
while (!status && Date.now() < deadline) {
|
|
412
|
+
await sleep(2e3);
|
|
413
|
+
status = await client.getUserChargingStatus();
|
|
414
|
+
}
|
|
339
415
|
if (!status) {
|
|
340
416
|
throw new APIError("No active charging session found after start command.");
|
|
341
417
|
}
|
|
@@ -377,7 +453,7 @@ var ChargePoint = class _ChargePoint {
|
|
|
377
453
|
return client;
|
|
378
454
|
}
|
|
379
455
|
_setToken(token, region) {
|
|
380
|
-
this._coulombToken = token;
|
|
456
|
+
this._coulombToken = decodeURIComponent(token);
|
|
381
457
|
this._region = region;
|
|
382
458
|
}
|
|
383
459
|
/** @internal Used by session.ts and tests. */
|
|
@@ -398,7 +474,7 @@ var ChargePoint = class _ChargePoint {
|
|
|
398
474
|
for (const cookie of setCookies) {
|
|
399
475
|
const match = /^coulomb_sess=([^;]+)/.exec(cookie);
|
|
400
476
|
if (match) {
|
|
401
|
-
this._coulombToken = match[1] ??
|
|
477
|
+
this._coulombToken = decodeURIComponent(match[1] ?? "");
|
|
402
478
|
break;
|
|
403
479
|
}
|
|
404
480
|
}
|
|
@@ -418,6 +494,13 @@ var ChargePoint = class _ChargePoint {
|
|
|
418
494
|
}
|
|
419
495
|
return response;
|
|
420
496
|
}
|
|
497
|
+
async _errorBody(response) {
|
|
498
|
+
try {
|
|
499
|
+
return await response.clone().text();
|
|
500
|
+
} catch {
|
|
501
|
+
return "";
|
|
502
|
+
}
|
|
503
|
+
}
|
|
421
504
|
// ---------------------------------------------------------------------------
|
|
422
505
|
// Authentication
|
|
423
506
|
// ---------------------------------------------------------------------------
|
|
@@ -624,8 +707,7 @@ var ChargePoint = class _ChargePoint {
|
|
|
624
707
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;
|
|
625
708
|
const response = await this._request("PUT", url, {
|
|
626
709
|
body: JSON.stringify({
|
|
627
|
-
|
|
628
|
-
userSchedule: {
|
|
710
|
+
schedule: {
|
|
629
711
|
weekdays: { startTime: weekdayStart, endTime: weekdayEnd },
|
|
630
712
|
weekends: { startTime: weekendStart, endTime: weekendEnd }
|
|
631
713
|
}
|
|
@@ -633,14 +715,15 @@ var ChargePoint = class _ChargePoint {
|
|
|
633
715
|
headers: { "Content-Type": "application/json" }
|
|
634
716
|
});
|
|
635
717
|
if (!response.ok) {
|
|
636
|
-
|
|
718
|
+
const body = await this._errorBody(response);
|
|
719
|
+
throw new CommunicationError(response.status, `Failed to set home charger schedule. HTTP ${response.status}: ${body}`);
|
|
637
720
|
}
|
|
638
721
|
return await response.json();
|
|
639
722
|
}
|
|
640
723
|
async disableHomeChargerSchedule(chargerId) {
|
|
641
724
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;
|
|
642
725
|
const response = await this._request("PUT", url, {
|
|
643
|
-
body: JSON.stringify({
|
|
726
|
+
body: JSON.stringify({}),
|
|
644
727
|
headers: { "Content-Type": "application/json" }
|
|
645
728
|
});
|
|
646
729
|
if (!response.ok) {
|
|
@@ -651,22 +734,24 @@ var ChargePoint = class _ChargePoint {
|
|
|
651
734
|
async setAmperageLimit(chargerId, amperageLimit) {
|
|
652
735
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/charge-amperage-limit`;
|
|
653
736
|
const response = await this._request("PUT", url, {
|
|
654
|
-
body: JSON.stringify({ amperageLimit }),
|
|
737
|
+
body: JSON.stringify({ chargeAmperageLimit: amperageLimit }),
|
|
655
738
|
headers: { "Content-Type": "application/json" }
|
|
656
739
|
});
|
|
657
740
|
if (!response.ok) {
|
|
658
|
-
|
|
741
|
+
const body = await this._errorBody(response);
|
|
742
|
+
throw new CommunicationError(response.status, `Failed to set amperage limit. HTTP ${response.status}: ${body}`);
|
|
659
743
|
}
|
|
660
744
|
await response.text();
|
|
661
745
|
}
|
|
662
746
|
async setLedBrightness(chargerId, level) {
|
|
663
747
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/led-brightness`;
|
|
664
748
|
const response = await this._request("PUT", url, {
|
|
665
|
-
body: JSON.stringify({ level }),
|
|
749
|
+
body: JSON.stringify({ ledBrightnessLevel: level }),
|
|
666
750
|
headers: { "Content-Type": "application/json" }
|
|
667
751
|
});
|
|
668
752
|
if (!response.ok) {
|
|
669
|
-
|
|
753
|
+
const body = await this._errorBody(response);
|
|
754
|
+
throw new CommunicationError(response.status, `Failed to set LED brightness. HTTP ${response.status}: ${body}`);
|
|
670
755
|
}
|
|
671
756
|
await response.text();
|
|
672
757
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -6,9 +6,13 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
6
6
|
|
|
7
7
|
var https__default = /*#__PURE__*/_interopDefault(https);
|
|
8
8
|
|
|
9
|
+
// package.json
|
|
10
|
+
var package_default = {
|
|
11
|
+
version: "0.3.5"};
|
|
12
|
+
|
|
9
13
|
// src/constants.ts
|
|
10
14
|
var DISCOVERY_API = "https://discovery.chargepoint.com/discovery/v3/globalconfig";
|
|
11
|
-
var VERSION =
|
|
15
|
+
var VERSION = package_default.version;
|
|
12
16
|
var USER_AGENT = `node-chargepoint/${VERSION}`;
|
|
13
17
|
|
|
14
18
|
// src/exceptions.ts
|
|
@@ -312,7 +316,12 @@ var ChargingSession = class _ChargingSession {
|
|
|
312
316
|
}
|
|
313
317
|
static async start(deviceId, client) {
|
|
314
318
|
await sendCommand(client, "start", deviceId);
|
|
315
|
-
const
|
|
319
|
+
const deadline = Date.now() + 15e3;
|
|
320
|
+
let status = await client.getUserChargingStatus();
|
|
321
|
+
while (!status && Date.now() < deadline) {
|
|
322
|
+
await sleep(2e3);
|
|
323
|
+
status = await client.getUserChargingStatus();
|
|
324
|
+
}
|
|
316
325
|
if (!status) {
|
|
317
326
|
throw new APIError("No active charging session found after start command.");
|
|
318
327
|
}
|
|
@@ -354,7 +363,7 @@ var ChargePoint = class _ChargePoint {
|
|
|
354
363
|
return client;
|
|
355
364
|
}
|
|
356
365
|
_setToken(token, region) {
|
|
357
|
-
this._coulombToken = token;
|
|
366
|
+
this._coulombToken = decodeURIComponent(token);
|
|
358
367
|
this._region = region;
|
|
359
368
|
}
|
|
360
369
|
/** @internal Used by session.ts and tests. */
|
|
@@ -375,7 +384,7 @@ var ChargePoint = class _ChargePoint {
|
|
|
375
384
|
for (const cookie of setCookies) {
|
|
376
385
|
const match = /^coulomb_sess=([^;]+)/.exec(cookie);
|
|
377
386
|
if (match) {
|
|
378
|
-
this._coulombToken = match[1] ??
|
|
387
|
+
this._coulombToken = decodeURIComponent(match[1] ?? "");
|
|
379
388
|
break;
|
|
380
389
|
}
|
|
381
390
|
}
|
|
@@ -395,6 +404,13 @@ var ChargePoint = class _ChargePoint {
|
|
|
395
404
|
}
|
|
396
405
|
return response;
|
|
397
406
|
}
|
|
407
|
+
async _errorBody(response) {
|
|
408
|
+
try {
|
|
409
|
+
return await response.clone().text();
|
|
410
|
+
} catch {
|
|
411
|
+
return "";
|
|
412
|
+
}
|
|
413
|
+
}
|
|
398
414
|
// ---------------------------------------------------------------------------
|
|
399
415
|
// Authentication
|
|
400
416
|
// ---------------------------------------------------------------------------
|
|
@@ -601,8 +617,7 @@ var ChargePoint = class _ChargePoint {
|
|
|
601
617
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;
|
|
602
618
|
const response = await this._request("PUT", url, {
|
|
603
619
|
body: JSON.stringify({
|
|
604
|
-
|
|
605
|
-
userSchedule: {
|
|
620
|
+
schedule: {
|
|
606
621
|
weekdays: { startTime: weekdayStart, endTime: weekdayEnd },
|
|
607
622
|
weekends: { startTime: weekendStart, endTime: weekendEnd }
|
|
608
623
|
}
|
|
@@ -610,14 +625,15 @@ var ChargePoint = class _ChargePoint {
|
|
|
610
625
|
headers: { "Content-Type": "application/json" }
|
|
611
626
|
});
|
|
612
627
|
if (!response.ok) {
|
|
613
|
-
|
|
628
|
+
const body = await this._errorBody(response);
|
|
629
|
+
throw new CommunicationError(response.status, `Failed to set home charger schedule. HTTP ${response.status}: ${body}`);
|
|
614
630
|
}
|
|
615
631
|
return await response.json();
|
|
616
632
|
}
|
|
617
633
|
async disableHomeChargerSchedule(chargerId) {
|
|
618
634
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;
|
|
619
635
|
const response = await this._request("PUT", url, {
|
|
620
|
-
body: JSON.stringify({
|
|
636
|
+
body: JSON.stringify({}),
|
|
621
637
|
headers: { "Content-Type": "application/json" }
|
|
622
638
|
});
|
|
623
639
|
if (!response.ok) {
|
|
@@ -628,22 +644,24 @@ var ChargePoint = class _ChargePoint {
|
|
|
628
644
|
async setAmperageLimit(chargerId, amperageLimit) {
|
|
629
645
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/charge-amperage-limit`;
|
|
630
646
|
const response = await this._request("PUT", url, {
|
|
631
|
-
body: JSON.stringify({ amperageLimit }),
|
|
647
|
+
body: JSON.stringify({ chargeAmperageLimit: amperageLimit }),
|
|
632
648
|
headers: { "Content-Type": "application/json" }
|
|
633
649
|
});
|
|
634
650
|
if (!response.ok) {
|
|
635
|
-
|
|
651
|
+
const body = await this._errorBody(response);
|
|
652
|
+
throw new CommunicationError(response.status, `Failed to set amperage limit. HTTP ${response.status}: ${body}`);
|
|
636
653
|
}
|
|
637
654
|
await response.text();
|
|
638
655
|
}
|
|
639
656
|
async setLedBrightness(chargerId, level) {
|
|
640
657
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/led-brightness`;
|
|
641
658
|
const response = await this._request("PUT", url, {
|
|
642
|
-
body: JSON.stringify({ level }),
|
|
659
|
+
body: JSON.stringify({ ledBrightnessLevel: level }),
|
|
643
660
|
headers: { "Content-Type": "application/json" }
|
|
644
661
|
});
|
|
645
662
|
if (!response.ok) {
|
|
646
|
-
|
|
663
|
+
const body = await this._errorBody(response);
|
|
664
|
+
throw new CommunicationError(response.status, `Failed to set LED brightness. HTTP ${response.status}: ${body}`);
|
|
647
665
|
}
|
|
648
666
|
await response.text();
|
|
649
667
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/exceptions.ts","../src/global-config.ts","../src/session.ts","../src/client.ts"],"names":["https","parseMsTimestamp"],"mappings":"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","file":"index.cjs","sourcesContent":["export const DISCOVERY_API =\n 'https://discovery.chargepoint.com/discovery/v3/globalconfig';\n\nexport const VERSION = '0.0.1-alpha.0';\nexport const USER_AGENT = `node-chargepoint/${VERSION}`;\n","export class APIError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'APIError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class CommunicationError extends APIError {\n constructor(\n public readonly statusCode: number,\n message: string,\n public readonly body?: unknown,\n ) {\n super(message);\n this.name = 'CommunicationError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class LoginError extends CommunicationError {\n constructor(statusCode: number, message: string, body?: unknown) {\n super(statusCode, message, body);\n this.name = 'LoginError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class InvalidSession extends CommunicationError {\n constructor(statusCode = 401, message = 'ChargePoint session expired. Please log in again.', body?: unknown) {\n super(statusCode, message, body);\n this.name = 'InvalidSession';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class DatadomeCaptcha extends APIError {\n constructor(\n public readonly captchaUrl: string,\n message = 'Datadome captcha protection triggered.',\n ) {\n super(message);\n this.name = 'DatadomeCaptcha';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import https from 'node:https';\nimport { DISCOVERY_API, USER_AGENT } from './constants.js';\nimport { CommunicationError } from './exceptions.js';\nimport type { APIEndpoints, GlobalConfiguration } from './types.js';\n\ntype RawValue = Record<string, unknown>;\n\n// Node 24's built-in fetch automatically adds `Sec-Fetch-Mode: cors`, which\n// causes the ChargePoint discovery endpoint to return HTTP 500. Using node:https\n// directly avoids that header. Default import (not named) is required so that\n// MSW's runtime patch of https.request is visible at call time in unit tests.\nasync function postJson(url: string, body: string): Promise<{ status: number; data: RawValue }> {\n return new Promise((resolve, reject) => {\n const bodyBuf = Buffer.from(body, 'utf-8');\n const req = https.request(\n url,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Content-Length': bodyBuf.byteLength,\n 'User-Agent': USER_AGENT,\n },\n },\n (res) => {\n const chunks: Buffer[] = [];\n res.on('data', (chunk: Buffer) => chunks.push(chunk));\n res.on('end', () => {\n const statusCode = res.statusCode ?? 0;\n if (statusCode < 200 || statusCode >= 300) {\n reject(new CommunicationError(statusCode, 'Failed to fetch global configuration.'));\n return;\n }\n try {\n resolve({ status: statusCode, data: JSON.parse(Buffer.concat(chunks).toString('utf-8')) as RawValue });\n } catch {\n reject(new CommunicationError(statusCode, 'Failed to parse global configuration response.'));\n }\n });\n },\n );\n req.on('error', (err: Error) => {\n reject(new CommunicationError(0, `Failed to reach ChargePoint discovery API: ${err.message}`));\n });\n req.write(bodyBuf);\n req.end();\n });\n}\n\nfunction endpointStr(v: unknown): string {\n const raw =\n v !== null && typeof v === 'object' && 'value' in v\n ? String((v as RawValue).value ?? '')\n : typeof v === 'string'\n ? v\n : '';\n return raw.replace(/\\/+$/, ''); // strip trailing slashes so callers can always do `${url}/path`\n}\n\nfunction parseEndpoints(raw: RawValue): APIEndpoints {\n // Support both camelCase and snake_case keys from the discovery API\n const get = (camel: string, snake: string): string =>\n endpointStr(raw[camel] ?? raw[snake] ?? '');\n\n return {\n accountsEndpoint: get('accountsEndpoint', 'accounts_endpoint'),\n internalApiGatewayEndpoint: get('internalApiGatewayEndpoint', 'internal_api_gateway_endpoint'),\n mapcacheEndpoint: get('mapcacheEndpoint', 'mapcache_endpoint'),\n pandaWebsocketEndpoint: get('pandaWebsocketEndpoint', 'panda_websocket_endpoint'),\n paymentJavaEndpoint: get('paymentJavaEndpoint', 'payment_java_endpoint'),\n paymentPhpEndpoint: get('paymentPhpEndpoint', 'payment_php_endpoint'),\n portalDomainEndpoint: get('portalDomainEndpoint', 'portal_domain_endpoint'),\n portalSubdomain:\n typeof raw.portalSubdomain === 'string'\n ? raw.portalSubdomain\n : typeof raw.portal_subdomain === 'string'\n ? raw.portal_subdomain\n : '',\n ssoEndpoint: get('ssoEndpoint', 'sso_endpoint'),\n webservicesEndpoint: get('webservicesEndpoint', 'webservices_endpoint'),\n websocketEndpoint: get('websocketEndpoint', 'websocket_endpoint'),\n hcpoHcmEndpoint: get('hcpoHcmEndpoint', 'hcpo_hcm_endpoint'),\n };\n}\n\nexport async function fetchGlobalConfig(region = 'NA'): Promise<GlobalConfiguration> {\n const { data } = await postJson(DISCOVERY_API, JSON.stringify({ regionCode: region }));\n\n // The API may return the config directly or nested under \"globalConfiguration\"\n const raw = (typeof data.globalConfiguration === 'object' && data.globalConfiguration !== null\n ? data.globalConfiguration\n : data) as RawValue;\n\n const endpointsRaw = (raw.endPoints ?? raw.endpoints ?? {}) as RawValue;\n\n return {\n region: typeof raw.region === 'string' ? raw.region : region,\n defaultCountry: (raw.defaultCountry ?? {}) as GlobalConfiguration['defaultCountry'],\n supportedCountries: Array.isArray(raw.supportedCountries)\n ? (raw.supportedCountries as GlobalConfiguration['supportedCountries'])\n : [],\n defaultCurrency: (raw.currency ?? raw.defaultCurrency ?? {}) as GlobalConfiguration['defaultCurrency'],\n supportedCurrencies: Array.isArray(raw.supportedCurrencies)\n ? (raw.supportedCurrencies as GlobalConfiguration['supportedCurrencies'])\n : [],\n endpoints: parseEndpoints(endpointsRaw),\n };\n}\n","import type { ChargePoint } from './client.js';\nimport { APIError, CommunicationError } from './exceptions.js';\nimport type { ChargingSessionUpdate, PowerUtility, VehicleInfo } from './types.js';\n\nconst sleep = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\ntype RawObj = Record<string, unknown>;\n\nexport async function sendCommand(\n client: ChargePoint,\n action: 'start' | 'stop',\n deviceId: number,\n portNumber = 1,\n sessionId = 0,\n): Promise<void> {\n const actionPath = action === 'start' ? 'startsession' : 'stopSession';\n const body: RawObj = { deviceId };\n\n if (action === 'stop') {\n body.portNumber = portNumber;\n body.sessionId = sessionId;\n }\n\n const url = `${client.globalConfig.endpoints.accountsEndpoint}/v1/driver/station/${actionPath}`;\n const response = await client._request('POST', url, {\n body: JSON.stringify(body),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new CommunicationError(\n response.status,\n `Failed to ${action} ChargePoint session: ${text}`,\n );\n }\n\n const actionStatus = (await response.json()) as RawObj;\n const ackId = actionStatus.ackId;\n\n const ackUrl = `${client.globalConfig.endpoints.accountsEndpoint}/v1/driver/station/session/ack`;\n\n let lastStatus = 0;\n let errorMessage = `Session failed to ${action}.`;\n let errorBody: unknown;\n\n for (let attempt = 1; attempt <= 20; attempt++) {\n const ackResponse = await client._request('POST', ackUrl, {\n body: JSON.stringify({ ackId, action: `${action}_session` }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n lastStatus = ackResponse.status;\n\n if (ackResponse.status === 200) {\n return;\n }\n\n try {\n errorBody = await ackResponse.json();\n const msg = (errorBody as RawObj).errorMessage;\n if (typeof msg === 'string') errorMessage = msg;\n } catch {\n errorBody = undefined;\n }\n\n if (attempt < 20) {\n await sleep(3000);\n }\n }\n\n throw new CommunicationError(lastStatus, errorMessage, errorBody);\n}\n\nfunction parseMsTimestamp(v: unknown): Date {\n if (typeof v === 'number') return new Date(v);\n if (typeof v === 'string') return new Date(Number(v));\n return new Date(0);\n}\n\nfunction parseSessionUpdates(raw: unknown): ChargingSessionUpdate[] {\n if (!Array.isArray(raw)) return [];\n return raw.map((u: unknown) => {\n const item = u as RawObj;\n return {\n energyKwh: typeof item.energy_kwh === 'number' ? item.energy_kwh : 0,\n powerKw: typeof item.power_kw === 'number' ? item.power_kw : 0,\n timestamp: parseMsTimestamp(item.timestamp),\n };\n });\n}\n\nexport class ChargingSession {\n sessionId: number;\n deviceId = 0;\n deviceName = '';\n chargingState = '';\n chargingTime = 0;\n energyKwh = 0;\n milesAdded = 0;\n milesAddedPerHour = 0;\n outletNumber = 0;\n portLevel = 0;\n powerKw = 0;\n purpose = '';\n currencyIsoCode = '';\n paymentCompleted = false;\n paymentType = '';\n pricingSpecId = 0;\n totalAmount = 0;\n apiFlag = false;\n enableStopCharging = false;\n hasChargingReceipt = false;\n hasUtilityInfo = false;\n isHomeCharger = false;\n isPurposeFinalized = false;\n stopChargeSupported = false;\n companyId = 0;\n companyName = '';\n latitude = 0;\n longitude = 0;\n address = '';\n city = '';\n stateName = '';\n country = '';\n zipcode = '';\n updatePeriod = 0;\n startTime: Date | null = null;\n lastUpdateDataTimestamp: Date | null = null;\n updateData: ChargingSessionUpdate[] | null = null;\n utility: PowerUtility | null = null;\n vehicleInfo: VehicleInfo | null = null;\n\n private _client: ChargePoint | null = null;\n\n constructor(sessionId: number) {\n this.sessionId = sessionId;\n }\n\n /** @internal */\n _setClient(client: ChargePoint): void {\n this._client = client;\n }\n\n /** @internal Apply raw session data from the driver-bff API (snake_case keys). */\n _apply(data: RawObj): void {\n if (data.device_id !== undefined) this.deviceId = data.device_id as number;\n if (data.device_name !== undefined) this.deviceName = data.device_name as string;\n if (data.current_charging !== undefined) this.chargingState = data.current_charging as string;\n if (data.charging_time !== undefined) this.chargingTime = data.charging_time as number;\n if (data.energy_kwh !== undefined) this.energyKwh = data.energy_kwh as number;\n if (data.miles_added !== undefined) this.milesAdded = data.miles_added as number;\n if (data.miles_added_per_hour !== undefined) this.milesAddedPerHour = data.miles_added_per_hour as number;\n if (data.outlet_number !== undefined) this.outletNumber = data.outlet_number as number;\n if (data.port_level !== undefined) this.portLevel = data.port_level as number;\n if (data.power_kw !== undefined) this.powerKw = data.power_kw as number;\n if (data.purpose !== undefined) this.purpose = data.purpose as string;\n if (data.currency_iso_code !== undefined) this.currencyIsoCode = String(data.currency_iso_code);\n if (data.payment_completed !== undefined) this.paymentCompleted = data.payment_completed as boolean;\n if (data.payment_type !== undefined) this.paymentType = data.payment_type as string;\n if (data.pricing_spec_id !== undefined) this.pricingSpecId = data.pricing_spec_id as number;\n if (data.total_amount !== undefined) this.totalAmount = data.total_amount as number;\n if (data.api_flag !== undefined) this.apiFlag = data.api_flag as boolean;\n if (data.enable_stop_charging !== undefined) this.enableStopCharging = data.enable_stop_charging as boolean;\n if (data.has_charging_receipt !== undefined) this.hasChargingReceipt = data.has_charging_receipt as boolean;\n if (data.has_utility_info !== undefined) this.hasUtilityInfo = data.has_utility_info as boolean;\n if (data.is_home_charger !== undefined) this.isHomeCharger = data.is_home_charger as boolean;\n if (data.is_purpose_finalized !== undefined) this.isPurposeFinalized = data.is_purpose_finalized as boolean;\n if (data.stop_charge_supported !== undefined) this.stopChargeSupported = data.stop_charge_supported as boolean;\n if (data.company_id !== undefined) this.companyId = data.company_id as number;\n if (data.company_name !== undefined) this.companyName = data.company_name as string;\n if (data.lat !== undefined) this.latitude = data.lat as number;\n if (data.lon !== undefined) this.longitude = data.lon as number;\n if (data.address1 !== undefined) this.address = data.address1 as string;\n if (data.city !== undefined) this.city = data.city as string;\n if (data.state_name !== undefined) this.stateName = data.state_name as string;\n if (data.country !== undefined) this.country = data.country as string;\n if (data.zipcode !== undefined) this.zipcode = data.zipcode as string;\n if (data.update_period !== undefined) this.updatePeriod = data.update_period as number;\n if (data.start_time !== undefined) this.startTime = parseMsTimestamp(data.start_time);\n if (data.last_update_data_timestamp !== undefined) {\n this.lastUpdateDataTimestamp = parseMsTimestamp(data.last_update_data_timestamp);\n }\n if (data.update_data !== undefined) this.updateData = parseSessionUpdates(data.update_data);\n if (data.utility !== undefined) this.utility = (data.utility as PowerUtility) ?? null;\n if (data.vehicle_info !== undefined) this.vehicleInfo = (data.vehicle_info as VehicleInfo) ?? null;\n }\n\n async refresh(): Promise<void> {\n if (!this._client) throw new Error('ChargingSession client not set.');\n\n const url = `${this._client.globalConfig.endpoints.internalApiGatewayEndpoint}/driver-bff/v1/sessions/${this.sessionId}`;\n const response = await this._client._request('POST', url, {\n body: JSON.stringify({\n charging_status: { session_id: this.sessionId, mfhs: [] },\n }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get charging session data.');\n }\n\n const json = (await response.json()) as RawObj;\n const status = json.charging_status as RawObj | undefined;\n\n if (!status || 'error_message' in status || 'error' in status) {\n throw new CommunicationError(response.status, 'Failed to get charging session data.');\n }\n\n this._apply(status);\n }\n\n async stop(): Promise<void> {\n if (!this._client) throw new Error('ChargingSession client not set.');\n await sendCommand(\n this._client,\n 'stop',\n this.deviceId,\n this.outletNumber,\n this.sessionId,\n );\n }\n\n static async start(deviceId: number, client: ChargePoint): Promise<ChargingSession> {\n await sendCommand(client, 'start', deviceId);\n // The sessionId returned by the start endpoint is not the real session ID;\n // fetch it from the status API instead.\n const status = await client.getUserChargingStatus();\n if (!status) {\n throw new APIError('No active charging session found after start command.');\n }\n const session = new ChargingSession(status.sessionId);\n session._setClient(client);\n await session.refresh();\n return session;\n }\n}\n","import { USER_AGENT } from './constants.js';\nimport { CommunicationError, DatadomeCaptcha, InvalidSession, LoginError } from './exceptions.js';\nimport { fetchGlobalConfig } from './global-config.js';\nimport { ChargingSession } from './session.js';\nimport type {\n Account,\n ElectricVehicle,\n GlobalConfiguration,\n HomeChargerConfiguration,\n HomeChargerSchedule,\n HomeChargerStatus,\n HomeChargerTechnicalInfo,\n MapFilter,\n MapStation,\n Station,\n StationInfo,\n UserChargingStatus,\n ZoomBounds,\n} from './types.js';\n\ntype RawObj = Record<string, unknown>;\n\nexport interface ChargePointOptions {\n coulombToken?: string;\n region?: string;\n}\n\nfunction parseMsTimestamp(v: unknown): Date {\n if (typeof v === 'number') return new Date(v);\n if (typeof v === 'string') return new Date(Number(v));\n return new Date(0);\n}\n\nexport class ChargePoint {\n public globalConfig: GlobalConfiguration;\n private _username: string;\n private _coulombToken: string | null = null;\n private _region: string;\n private _userId: number | null = null;\n\n /** The current session token. Save this after login to avoid re-authenticating. */\n get coulombToken(): string | null {\n return this._coulombToken;\n }\n\n private constructor(username: string, globalConfig: GlobalConfiguration, region: string) {\n this._username = username;\n this.globalConfig = globalConfig;\n this._region = region;\n }\n\n static async create(username: string, options: ChargePointOptions = {}): Promise<ChargePoint> {\n const region = options.region ?? 'NA';\n const config = await fetchGlobalConfig(region);\n const client = new ChargePoint(username, config, region);\n\n if (options.coulombToken) {\n client._setToken(options.coulombToken, region);\n }\n\n return client;\n }\n\n private _setToken(token: string, region: string): void {\n this._coulombToken = token;\n this._region = region;\n }\n\n /** @internal Used by session.ts and tests. */\n async _request(method: string, url: string, init: RequestInit = {}): Promise<Response> {\n const headers = new Headers(init.headers as string[][] | Record<string, string> | Headers);\n headers.set('user-agent', USER_AGENT);\n\n if (!headers.has('content-type') && method !== 'GET') {\n headers.set('content-type', 'application/json');\n }\n\n if (this._coulombToken) {\n headers.set('cookie', `coulomb_sess=${this._coulombToken}`);\n headers.set('cp-session-type', 'CP_SESSION_TOKEN');\n headers.set('cp-session-token', this._coulombToken);\n headers.set('cp-region', this._region);\n }\n\n const response = await fetch(url, { ...init, method, headers });\n\n // Refresh coulomb_sess from Set-Cookie response header\n const setCookies: string[] =\n typeof (response.headers as unknown as { getSetCookie?: () => string[] }).getSetCookie ===\n 'function'\n ? (response.headers as unknown as { getSetCookie: () => string[] }).getSetCookie()\n : [response.headers.get('set-cookie') ?? ''].filter(Boolean);\n\n for (const cookie of setCookies) {\n const match = /^coulomb_sess=([^;]+)/.exec(cookie);\n if (match) {\n this._coulombToken = match[1] ?? null;\n break;\n }\n }\n\n if (response.status === 401) {\n throw new InvalidSession(401, 'ChargePoint session expired. Please log in again.');\n }\n\n if (response.status === 403) {\n let body: unknown;\n try {\n body = await response.clone().json();\n } catch {\n // not JSON\n }\n const captchaUrl = (body as RawObj)?.url;\n if (typeof captchaUrl === 'string' && captchaUrl.includes('datadome')) {\n throw new DatadomeCaptcha(captchaUrl);\n }\n }\n\n return response;\n }\n\n // ---------------------------------------------------------------------------\n // Authentication\n // ---------------------------------------------------------------------------\n\n async loginWithPassword(password: string): Promise<void> {\n const url = `${this.globalConfig.endpoints.ssoEndpoint}/v1/user/login`;\n const response = await this._request('POST', url, {\n body: JSON.stringify({ user_name: this._username, password }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new LoginError(response.status, 'Failed to login with password.', body);\n }\n\n // The coulomb_sess cookie is set by the SSO endpoint on success;\n // _request() already extracted it from Set-Cookie above.\n await response.text(); // drain body\n\n if (!this._coulombToken) {\n throw new LoginError(response.status, 'Login succeeded but no session token was returned.');\n }\n }\n\n async loginWithSsoSession(ssoJwt: string): Promise<void> {\n // Exchange an SSO JWT for a coulomb_sess cookie via the portal endpoint.\n const url = `${this.globalConfig.endpoints.portalDomainEndpoint}/index.php/nghelper/getSession`;\n const response = await this._request('GET', url, {\n headers: {\n cookie: `auth-session=${ssoJwt}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new LoginError(response.status, 'Failed to login with SSO session.', body);\n }\n\n await response.text();\n }\n\n async logout(): Promise<void> {\n const url = `${this.globalConfig.endpoints.ssoEndpoint}/v1/user/logout`;\n try {\n await this._request('POST', url);\n } finally {\n this._coulombToken = null;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Account\n // ---------------------------------------------------------------------------\n\n async getAccount(): Promise<Account> {\n const url = `${this.globalConfig.endpoints.accountsEndpoint}/v1/driver/profile/user`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get account information.');\n }\n\n const data = (await response.json()) as Account;\n if (data.user?.userId) {\n this._userId = data.user.userId;\n }\n return data;\n }\n\n async getVehicles(): Promise<ElectricVehicle[]> {\n const url = `${this.globalConfig.endpoints.accountsEndpoint}/v1/driver/vehicle`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get vehicles.');\n }\n\n const data = (await response.json()) as RawObj;\n return (Array.isArray(data.vehicles) ? data.vehicles : []) as ElectricVehicle[];\n }\n\n async getUserChargingStatus(): Promise<UserChargingStatus | null> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v2`;\n const response = await this._request('POST', url, {\n body: JSON.stringify({ user_status: { timestamp: Date.now() } }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get user charging status.');\n }\n\n const data = (await response.json()) as RawObj;\n const userStatus = data.user_status as RawObj | null | undefined;\n\n if (!userStatus) return null;\n\n const charging = userStatus.charging_status as RawObj | null | undefined;\n if (!charging) return null;\n\n const stations: Station[] = Array.isArray(charging.stations)\n ? (charging.stations as RawObj[]).map((s) => ({\n id: s.id as number,\n name: typeof s.name === 'string' ? s.name : '',\n latitude: typeof s.lat === 'number' ? s.lat : (s.latitude as number ?? 0),\n longitude: typeof s.lon === 'number' ? s.lon : (s.longitude as number ?? 0),\n }))\n : [];\n\n return {\n sessionId: charging.session_id as number,\n startTime: parseMsTimestamp(charging.start_time),\n state: typeof charging.current_charging === 'string' ? charging.current_charging : '',\n stations,\n };\n }\n\n // ---------------------------------------------------------------------------\n // Home charger helpers\n // ---------------------------------------------------------------------------\n\n private async ensureUserId(): Promise<number> {\n if (this._userId !== null) return this._userId;\n const account = await this.getAccount();\n return account.user.userId;\n }\n\n async getHomeChargers(): Promise<number[]> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new CommunicationError(response.status, 'Failed to get home chargers.', body);\n }\n\n const data = (await response.json()) as RawObj;\n // API returns { data: [...] }; older shape used { chargers: [...] }\n const arr = Array.isArray(data.data)\n ? (data.data as RawObj[])\n : Array.isArray(data.chargers)\n ? (data.chargers as RawObj[])\n : [];\n return arr.map((c) => {\n // API uses \"id\" (string); older shape used chargerId / charger_id (number)\n const id = c.id ?? c.chargerId ?? c.charger_id;\n return typeof id === 'number' ? id : Number(id);\n });\n }\n\n async getHomeChargerStatus(chargerId: number): Promise<HomeChargerStatus> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/status`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger status.');\n }\n\n const data = (await response.json()) as RawObj;\n // Real API nests amperage info under chargeAmperageSettings; fall back to flat fields for older shapes\n const amp = (data.chargeAmperageSettings ?? {}) as RawObj;\n return {\n chargerId, // not echoed by the API; inject from parameter\n brand: String(data.brand ?? ''),\n model: String(data.model ?? ''),\n macAddress: String(data.macAddress ?? ''),\n chargingStatus: String(data.chargingStatus ?? ''),\n isPluggedIn: Boolean(data.isPluggedIn),\n isConnected: Boolean(data.isConnected),\n isReminderEnabled: Boolean(data.isReminderEnabled),\n plugInReminderTime: String(data.plugInReminderTime ?? ''),\n hasUtilityInfo: Boolean(data.hasUtilityInfo),\n isDuringScheduledTime: Boolean(data.isDuringScheduledTime),\n amperageLimit: Number(amp.chargeLimit ?? data.amperageLimit ?? 0),\n possibleAmperageLimits: ((amp.possibleChargeLimit ?? data.possibleAmperageLimits ?? []) as number[]).map(Number),\n };\n }\n\n async getHomeChargerTechnicalInfo(chargerId: number): Promise<HomeChargerTechnicalInfo> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/technical-info`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger technical info.');\n }\n\n return (await response.json()) as HomeChargerTechnicalInfo;\n }\n\n async getHomeChargerConfig(chargerId: number): Promise<HomeChargerConfiguration> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/configurations`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger configuration.');\n }\n\n const data = (await response.json()) as RawObj;\n // Real API wraps all fields under \"settings\"; fall back to flat shape for older responses\n const s = (data.settings ?? data) as RawObj;\n // LED brightness: real API uses settings.led.brightness with string-typed level/supportedLevels\n const rawLed = ((s.led as RawObj | undefined)?.brightness ?? s.ledBrightness ?? {}) as RawObj;\n const level =\n typeof rawLed.level === 'string'\n ? Number(rawLed.level)\n : Number(rawLed.level ?? rawLed.currentBrightnessSettings ?? 0);\n const supportedLevels = Array.isArray(rawLed.supportedLevels)\n ? (rawLed.supportedLevels as (string | number)[]).map(Number)\n : [];\n return {\n serialNumber: String(s.serialNumber ?? ''),\n macAddress: String(s.macAddress ?? ''),\n stationNickname: String(s.stationNickname ?? ''),\n streetAddress: String(s.streetAddress ?? ''),\n hasUtilityInfo: Boolean(s.hasUtilityInfo),\n utility: (s.utility ?? null) as HomeChargerConfiguration['utility'],\n // API may return boolean true/false or string \"ON\"/\"OFF\"\n indicatorLightEcoMode: s.indicatorLightEcoMode === true || s.indicatorLightEcoMode === 'ON',\n flashlightReset: Boolean(s.flashlightReset),\n worksWithNest: Boolean(s.worksWithNest),\n isPairedWithNest: Boolean(s.isPairedWithNest),\n isInstalledByInstaller: Boolean(s.isInstalledByInstaller),\n ledBrightness: {\n level,\n inProgress: Boolean(rawLed.inProgress),\n supportedLevels,\n isEnabled: rawLed.isEnabled !== false,\n },\n };\n }\n\n async getHomeChargerSchedule(chargerId: number): Promise<HomeChargerSchedule> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger schedule.');\n }\n\n return (await response.json()) as HomeChargerSchedule;\n }\n\n async setHomeChargerSchedule(\n chargerId: number,\n weekdayStart: string,\n weekdayEnd: string,\n weekendStart: string,\n weekendEnd: string,\n ): Promise<HomeChargerSchedule> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({\n scheduleEnabled: true,\n userSchedule: {\n weekdays: { startTime: weekdayStart, endTime: weekdayEnd },\n weekends: { startTime: weekendStart, endTime: weekendEnd },\n },\n }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to set home charger schedule.');\n }\n\n return (await response.json()) as HomeChargerSchedule;\n }\n\n async disableHomeChargerSchedule(chargerId: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({ scheduleEnabled: false }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to disable home charger schedule.');\n }\n\n await response.text();\n }\n\n async setAmperageLimit(chargerId: number, amperageLimit: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/charge-amperage-limit`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({ amperageLimit }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to set amperage limit.');\n }\n\n await response.text();\n }\n\n async setLedBrightness(chargerId: number, level: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/led-brightness`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({ level }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to set LED brightness.');\n }\n\n await response.text();\n }\n\n async restartHomeCharger(chargerId: number): Promise<void> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/restart`;\n const response = await this._request('POST', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to restart home charger.');\n }\n\n await response.text();\n }\n\n // ---------------------------------------------------------------------------\n // Charging sessions\n // ---------------------------------------------------------------------------\n\n async getChargingSession(sessionId: number): Promise<ChargingSession> {\n const session = new ChargingSession(sessionId);\n session._setClient(this);\n await session.refresh();\n return session;\n }\n\n async startChargingSession(deviceId: number): Promise<ChargingSession> {\n return ChargingSession.start(deviceId, this);\n }\n\n // ---------------------------------------------------------------------------\n // Stations\n // ---------------------------------------------------------------------------\n\n async getStation(deviceId: number): Promise<StationInfo> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v3/station/info?deviceId=${deviceId}&use_cache=false`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get station info.');\n }\n\n return (await response.json()) as StationInfo;\n }\n\n async getNearbyStations(bounds: ZoomBounds, filter: MapFilter = {}): Promise<MapStation[]> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v2`;\n const stationList: RawObj = {\n ne_lat: bounds.neLat,\n ne_lon: bounds.neLon,\n sw_lat: bounds.swLat,\n sw_lon: bounds.swLon,\n ...filter,\n };\n\n const response = await this._request('POST', url, {\n body: JSON.stringify({ station_list: stationList }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get nearby stations.');\n }\n\n const data = (await response.json()) as RawObj;\n const list = data.station_list as RawObj | undefined;\n return Array.isArray(list?.stations) ? (list.stations as MapStation[]) : [];\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/constants.ts","../src/exceptions.ts","../src/global-config.ts","../src/session.ts","../src/client.ts"],"names":["https","parseMsTimestamp"],"mappings":"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","file":"index.cjs","sourcesContent":["{\n \"name\": \"node-chargepoint\",\n \"version\": \"0.3.5\",\n \"description\": \"A Node.js/TypeScript wrapper for the ChargePoint EV charging network API. Based on python-chargepoint by Marc Billow.\",\n \"keywords\": [\n \"chargepoint\",\n \"ev\",\n \"electric-vehicle\",\n \"charging\",\n \"evse\"\n ],\n \"homepage\": \"https://github.com/musicbender/node-chargepoint\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/musicbender/node-chargepoint.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/musicbender/node-chargepoint/issues\"\n },\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n }\n }\n },\n \"bin\": {\n \"chargepoint\": \"./dist/cli.cjs\"\n },\n \"files\": [\n \"dist\",\n \"LICENSE\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"eslint src tests\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:e2e\": \"vitest run --config vitest.e2e.config.ts\",\n \"prepublishOnly\": \"pnpm build && pnpm typecheck\"\n },\n \"engines\": {\n \"node\": \">=24\"\n },\n \"packageManager\": \"pnpm@11.0.9+sha512.34ce82e6780233cf9cad8685029a8f81d2e06196c5a9bad98879f7424940c6817c4e4524fb7d38b8553ceed48b9758b8ebaf1abd3600c232c4c8cf7366086f38\",\n \"dependencies\": {\n \"commander\": \"^12.1.0\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^22.0.0\",\n \"eslint\": \"^10.3.0\",\n \"msw\": \"^2.7.0\",\n \"tsup\": \"^8.3.0\",\n \"typescript\": \"^5.8.0\",\n \"typescript-eslint\": \"^8.59.2\",\n \"vitest\": \"^2.1.0\"\n }\n}\n","import pkg from '../package.json' with { type: 'json' };\n\nexport const DISCOVERY_API =\n 'https://discovery.chargepoint.com/discovery/v3/globalconfig';\n\nexport const VERSION: string = pkg.version;\nexport const USER_AGENT = `node-chargepoint/${VERSION}`;\n","export class APIError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'APIError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class CommunicationError extends APIError {\n constructor(\n public readonly statusCode: number,\n message: string,\n public readonly body?: unknown,\n ) {\n super(message);\n this.name = 'CommunicationError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class LoginError extends CommunicationError {\n constructor(statusCode: number, message: string, body?: unknown) {\n super(statusCode, message, body);\n this.name = 'LoginError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class InvalidSession extends CommunicationError {\n constructor(statusCode = 401, message = 'ChargePoint session expired. Please log in again.', body?: unknown) {\n super(statusCode, message, body);\n this.name = 'InvalidSession';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class DatadomeCaptcha extends APIError {\n constructor(\n public readonly captchaUrl: string,\n message = 'Datadome captcha protection triggered.',\n ) {\n super(message);\n this.name = 'DatadomeCaptcha';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import https from 'node:https';\nimport { DISCOVERY_API, USER_AGENT } from './constants.js';\nimport { CommunicationError } from './exceptions.js';\nimport type { APIEndpoints, GlobalConfiguration } from './types.js';\n\ntype RawValue = Record<string, unknown>;\n\n// Node 24's built-in fetch automatically adds `Sec-Fetch-Mode: cors`, which\n// causes the ChargePoint discovery endpoint to return HTTP 500. Using node:https\n// directly avoids that header. Default import (not named) is required so that\n// MSW's runtime patch of https.request is visible at call time in unit tests.\nasync function postJson(url: string, body: string): Promise<{ status: number; data: RawValue }> {\n return new Promise((resolve, reject) => {\n const bodyBuf = Buffer.from(body, 'utf-8');\n const req = https.request(\n url,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Content-Length': bodyBuf.byteLength,\n 'User-Agent': USER_AGENT,\n },\n },\n (res) => {\n const chunks: Buffer[] = [];\n res.on('data', (chunk: Buffer) => chunks.push(chunk));\n res.on('end', () => {\n const statusCode = res.statusCode ?? 0;\n if (statusCode < 200 || statusCode >= 300) {\n reject(new CommunicationError(statusCode, 'Failed to fetch global configuration.'));\n return;\n }\n try {\n resolve({ status: statusCode, data: JSON.parse(Buffer.concat(chunks).toString('utf-8')) as RawValue });\n } catch {\n reject(new CommunicationError(statusCode, 'Failed to parse global configuration response.'));\n }\n });\n },\n );\n req.on('error', (err: Error) => {\n reject(new CommunicationError(0, `Failed to reach ChargePoint discovery API: ${err.message}`));\n });\n req.write(bodyBuf);\n req.end();\n });\n}\n\nfunction endpointStr(v: unknown): string {\n const raw =\n v !== null && typeof v === 'object' && 'value' in v\n ? String((v as RawValue).value ?? '')\n : typeof v === 'string'\n ? v\n : '';\n return raw.replace(/\\/+$/, ''); // strip trailing slashes so callers can always do `${url}/path`\n}\n\nfunction parseEndpoints(raw: RawValue): APIEndpoints {\n // Support both camelCase and snake_case keys from the discovery API\n const get = (camel: string, snake: string): string =>\n endpointStr(raw[camel] ?? raw[snake] ?? '');\n\n return {\n accountsEndpoint: get('accountsEndpoint', 'accounts_endpoint'),\n internalApiGatewayEndpoint: get('internalApiGatewayEndpoint', 'internal_api_gateway_endpoint'),\n mapcacheEndpoint: get('mapcacheEndpoint', 'mapcache_endpoint'),\n pandaWebsocketEndpoint: get('pandaWebsocketEndpoint', 'panda_websocket_endpoint'),\n paymentJavaEndpoint: get('paymentJavaEndpoint', 'payment_java_endpoint'),\n paymentPhpEndpoint: get('paymentPhpEndpoint', 'payment_php_endpoint'),\n portalDomainEndpoint: get('portalDomainEndpoint', 'portal_domain_endpoint'),\n portalSubdomain:\n typeof raw.portalSubdomain === 'string'\n ? raw.portalSubdomain\n : typeof raw.portal_subdomain === 'string'\n ? raw.portal_subdomain\n : '',\n ssoEndpoint: get('ssoEndpoint', 'sso_endpoint'),\n webservicesEndpoint: get('webservicesEndpoint', 'webservices_endpoint'),\n websocketEndpoint: get('websocketEndpoint', 'websocket_endpoint'),\n hcpoHcmEndpoint: get('hcpoHcmEndpoint', 'hcpo_hcm_endpoint'),\n };\n}\n\nexport async function fetchGlobalConfig(region = 'NA'): Promise<GlobalConfiguration> {\n const { data } = await postJson(DISCOVERY_API, JSON.stringify({ regionCode: region }));\n\n // The API may return the config directly or nested under \"globalConfiguration\"\n const raw = (typeof data.globalConfiguration === 'object' && data.globalConfiguration !== null\n ? data.globalConfiguration\n : data) as RawValue;\n\n const endpointsRaw = (raw.endPoints ?? raw.endpoints ?? {}) as RawValue;\n\n return {\n region: typeof raw.region === 'string' ? raw.region : region,\n defaultCountry: (raw.defaultCountry ?? {}) as GlobalConfiguration['defaultCountry'],\n supportedCountries: Array.isArray(raw.supportedCountries)\n ? (raw.supportedCountries as GlobalConfiguration['supportedCountries'])\n : [],\n defaultCurrency: (raw.currency ?? raw.defaultCurrency ?? {}) as GlobalConfiguration['defaultCurrency'],\n supportedCurrencies: Array.isArray(raw.supportedCurrencies)\n ? (raw.supportedCurrencies as GlobalConfiguration['supportedCurrencies'])\n : [],\n endpoints: parseEndpoints(endpointsRaw),\n };\n}\n","import type { ChargePoint } from './client.js';\nimport { APIError, CommunicationError } from './exceptions.js';\nimport type { ChargingSessionUpdate, PowerUtility, VehicleInfo } from './types.js';\n\nconst sleep = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\ntype RawObj = Record<string, unknown>;\n\nexport async function sendCommand(\n client: ChargePoint,\n action: 'start' | 'stop',\n deviceId: number,\n portNumber = 1,\n sessionId = 0,\n): Promise<void> {\n const actionPath = action === 'start' ? 'startsession' : 'stopSession';\n const body: RawObj = { deviceId };\n\n if (action === 'stop') {\n body.portNumber = portNumber;\n body.sessionId = sessionId;\n }\n\n const url = `${client.globalConfig.endpoints.accountsEndpoint}/v1/driver/station/${actionPath}`;\n const response = await client._request('POST', url, {\n body: JSON.stringify(body),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new CommunicationError(\n response.status,\n `Failed to ${action} ChargePoint session: ${text}`,\n );\n }\n\n const actionStatus = (await response.json()) as RawObj;\n const ackId = actionStatus.ackId;\n\n const ackUrl = `${client.globalConfig.endpoints.accountsEndpoint}/v1/driver/station/session/ack`;\n\n let lastStatus = 0;\n let errorMessage = `Session failed to ${action}.`;\n let errorBody: unknown;\n\n for (let attempt = 1; attempt <= 20; attempt++) {\n const ackResponse = await client._request('POST', ackUrl, {\n body: JSON.stringify({ ackId, action: `${action}_session` }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n lastStatus = ackResponse.status;\n\n if (ackResponse.status === 200) {\n return;\n }\n\n try {\n errorBody = await ackResponse.json();\n const msg = (errorBody as RawObj).errorMessage;\n if (typeof msg === 'string') errorMessage = msg;\n } catch {\n errorBody = undefined;\n }\n\n if (attempt < 20) {\n await sleep(3000);\n }\n }\n\n throw new CommunicationError(lastStatus, errorMessage, errorBody);\n}\n\nfunction parseMsTimestamp(v: unknown): Date {\n if (typeof v === 'number') return new Date(v);\n if (typeof v === 'string') return new Date(Number(v));\n return new Date(0);\n}\n\nfunction parseSessionUpdates(raw: unknown): ChargingSessionUpdate[] {\n if (!Array.isArray(raw)) return [];\n return raw.map((u: unknown) => {\n const item = u as RawObj;\n return {\n energyKwh: typeof item.energy_kwh === 'number' ? item.energy_kwh : 0,\n powerKw: typeof item.power_kw === 'number' ? item.power_kw : 0,\n timestamp: parseMsTimestamp(item.timestamp),\n };\n });\n}\n\nexport class ChargingSession {\n sessionId: number;\n deviceId = 0;\n deviceName = '';\n chargingState = '';\n chargingTime = 0;\n energyKwh = 0;\n milesAdded = 0;\n milesAddedPerHour = 0;\n outletNumber = 0;\n portLevel = 0;\n powerKw = 0;\n purpose = '';\n currencyIsoCode = '';\n paymentCompleted = false;\n paymentType = '';\n pricingSpecId = 0;\n totalAmount = 0;\n apiFlag = false;\n enableStopCharging = false;\n hasChargingReceipt = false;\n hasUtilityInfo = false;\n isHomeCharger = false;\n isPurposeFinalized = false;\n stopChargeSupported = false;\n companyId = 0;\n companyName = '';\n latitude = 0;\n longitude = 0;\n address = '';\n city = '';\n stateName = '';\n country = '';\n zipcode = '';\n updatePeriod = 0;\n startTime: Date | null = null;\n lastUpdateDataTimestamp: Date | null = null;\n updateData: ChargingSessionUpdate[] | null = null;\n utility: PowerUtility | null = null;\n vehicleInfo: VehicleInfo | null = null;\n\n private _client: ChargePoint | null = null;\n\n constructor(sessionId: number) {\n this.sessionId = sessionId;\n }\n\n /** @internal */\n _setClient(client: ChargePoint): void {\n this._client = client;\n }\n\n /** @internal Apply raw session data from the driver-bff API (snake_case keys). */\n _apply(data: RawObj): void {\n if (data.device_id !== undefined) this.deviceId = data.device_id as number;\n if (data.device_name !== undefined) this.deviceName = data.device_name as string;\n if (data.current_charging !== undefined) this.chargingState = data.current_charging as string;\n if (data.charging_time !== undefined) this.chargingTime = data.charging_time as number;\n if (data.energy_kwh !== undefined) this.energyKwh = data.energy_kwh as number;\n if (data.miles_added !== undefined) this.milesAdded = data.miles_added as number;\n if (data.miles_added_per_hour !== undefined) this.milesAddedPerHour = data.miles_added_per_hour as number;\n if (data.outlet_number !== undefined) this.outletNumber = data.outlet_number as number;\n if (data.port_level !== undefined) this.portLevel = data.port_level as number;\n if (data.power_kw !== undefined) this.powerKw = data.power_kw as number;\n if (data.purpose !== undefined) this.purpose = data.purpose as string;\n if (data.currency_iso_code !== undefined) this.currencyIsoCode = String(data.currency_iso_code);\n if (data.payment_completed !== undefined) this.paymentCompleted = data.payment_completed as boolean;\n if (data.payment_type !== undefined) this.paymentType = data.payment_type as string;\n if (data.pricing_spec_id !== undefined) this.pricingSpecId = data.pricing_spec_id as number;\n if (data.total_amount !== undefined) this.totalAmount = data.total_amount as number;\n if (data.api_flag !== undefined) this.apiFlag = data.api_flag as boolean;\n if (data.enable_stop_charging !== undefined) this.enableStopCharging = data.enable_stop_charging as boolean;\n if (data.has_charging_receipt !== undefined) this.hasChargingReceipt = data.has_charging_receipt as boolean;\n if (data.has_utility_info !== undefined) this.hasUtilityInfo = data.has_utility_info as boolean;\n if (data.is_home_charger !== undefined) this.isHomeCharger = data.is_home_charger as boolean;\n if (data.is_purpose_finalized !== undefined) this.isPurposeFinalized = data.is_purpose_finalized as boolean;\n if (data.stop_charge_supported !== undefined) this.stopChargeSupported = data.stop_charge_supported as boolean;\n if (data.company_id !== undefined) this.companyId = data.company_id as number;\n if (data.company_name !== undefined) this.companyName = data.company_name as string;\n if (data.lat !== undefined) this.latitude = data.lat as number;\n if (data.lon !== undefined) this.longitude = data.lon as number;\n if (data.address1 !== undefined) this.address = data.address1 as string;\n if (data.city !== undefined) this.city = data.city as string;\n if (data.state_name !== undefined) this.stateName = data.state_name as string;\n if (data.country !== undefined) this.country = data.country as string;\n if (data.zipcode !== undefined) this.zipcode = data.zipcode as string;\n if (data.update_period !== undefined) this.updatePeriod = data.update_period as number;\n if (data.start_time !== undefined) this.startTime = parseMsTimestamp(data.start_time);\n if (data.last_update_data_timestamp !== undefined) {\n this.lastUpdateDataTimestamp = parseMsTimestamp(data.last_update_data_timestamp);\n }\n if (data.update_data !== undefined) this.updateData = parseSessionUpdates(data.update_data);\n if (data.utility !== undefined) this.utility = (data.utility as PowerUtility) ?? null;\n if (data.vehicle_info !== undefined) this.vehicleInfo = (data.vehicle_info as VehicleInfo) ?? null;\n }\n\n async refresh(): Promise<void> {\n if (!this._client) throw new Error('ChargingSession client not set.');\n\n const url = `${this._client.globalConfig.endpoints.internalApiGatewayEndpoint}/driver-bff/v1/sessions/${this.sessionId}`;\n const response = await this._client._request('POST', url, {\n body: JSON.stringify({\n charging_status: { session_id: this.sessionId, mfhs: [] },\n }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get charging session data.');\n }\n\n const json = (await response.json()) as RawObj;\n const status = json.charging_status as RawObj | undefined;\n\n if (!status || 'error_message' in status || 'error' in status) {\n throw new CommunicationError(response.status, 'Failed to get charging session data.');\n }\n\n this._apply(status);\n }\n\n async stop(): Promise<void> {\n if (!this._client) throw new Error('ChargingSession client not set.');\n await sendCommand(\n this._client,\n 'stop',\n this.deviceId,\n this.outletNumber,\n this.sessionId,\n );\n }\n\n static async start(deviceId: number, client: ChargePoint): Promise<ChargingSession> {\n await sendCommand(client, 'start', deviceId);\n\n // The start ack confirms the cloud received the command, but the session\n // may take a moment to appear in the status API (same async IoT pattern\n // as amperage/LED changes). Poll until it shows up.\n const deadline = Date.now() + 15_000;\n let status = await client.getUserChargingStatus();\n while (!status && Date.now() < deadline) {\n await sleep(2000);\n status = await client.getUserChargingStatus();\n }\n\n if (!status) {\n throw new APIError('No active charging session found after start command.');\n }\n const session = new ChargingSession(status.sessionId);\n session._setClient(client);\n await session.refresh();\n return session;\n }\n}\n","import { USER_AGENT } from './constants.js';\nimport { CommunicationError, DatadomeCaptcha, InvalidSession, LoginError } from './exceptions.js';\nimport { fetchGlobalConfig } from './global-config.js';\nimport { ChargingSession } from './session.js';\nimport type {\n Account,\n ElectricVehicle,\n GlobalConfiguration,\n HomeChargerConfiguration,\n HomeChargerSchedule,\n HomeChargerStatus,\n HomeChargerTechnicalInfo,\n MapFilter,\n MapStation,\n Station,\n StationInfo,\n UserChargingStatus,\n ZoomBounds,\n} from './types.js';\n\ntype RawObj = Record<string, unknown>;\n\nexport interface ChargePointOptions {\n coulombToken?: string;\n region?: string;\n}\n\nfunction parseMsTimestamp(v: unknown): Date {\n if (typeof v === 'number') return new Date(v);\n if (typeof v === 'string') return new Date(Number(v));\n return new Date(0);\n}\n\nexport class ChargePoint {\n public globalConfig: GlobalConfiguration;\n private _username: string;\n private _coulombToken: string | null = null;\n private _region: string;\n private _userId: number | null = null;\n\n /** The current session token. Save this after login to avoid re-authenticating. */\n get coulombToken(): string | null {\n return this._coulombToken;\n }\n\n private constructor(username: string, globalConfig: GlobalConfiguration, region: string) {\n this._username = username;\n this.globalConfig = globalConfig;\n this._region = region;\n }\n\n static async create(username: string, options: ChargePointOptions = {}): Promise<ChargePoint> {\n const region = options.region ?? 'NA';\n const config = await fetchGlobalConfig(region);\n const client = new ChargePoint(username, config, region);\n\n if (options.coulombToken) {\n client._setToken(options.coulombToken, region);\n }\n\n return client;\n }\n\n private _setToken(token: string, region: string): void {\n this._coulombToken = decodeURIComponent(token);\n this._region = region;\n }\n\n /** @internal Used by session.ts and tests. */\n async _request(method: string, url: string, init: RequestInit = {}): Promise<Response> {\n const headers = new Headers(init.headers as string[][] | Record<string, string> | Headers);\n headers.set('user-agent', USER_AGENT);\n\n if (!headers.has('content-type') && method !== 'GET') {\n headers.set('content-type', 'application/json');\n }\n\n if (this._coulombToken) {\n headers.set('cookie', `coulomb_sess=${this._coulombToken}`);\n headers.set('cp-session-type', 'CP_SESSION_TOKEN');\n headers.set('cp-session-token', this._coulombToken);\n headers.set('cp-region', this._region);\n }\n\n const response = await fetch(url, { ...init, method, headers });\n\n // Refresh coulomb_sess from Set-Cookie response header\n const setCookies: string[] =\n typeof (response.headers as unknown as { getSetCookie?: () => string[] }).getSetCookie ===\n 'function'\n ? (response.headers as unknown as { getSetCookie: () => string[] }).getSetCookie()\n : [response.headers.get('set-cookie') ?? ''].filter(Boolean);\n\n for (const cookie of setCookies) {\n const match = /^coulomb_sess=([^;]+)/.exec(cookie);\n if (match) {\n this._coulombToken = decodeURIComponent(match[1] ?? '');\n break;\n }\n }\n\n if (response.status === 401) {\n throw new InvalidSession(401, 'ChargePoint session expired. Please log in again.');\n }\n\n if (response.status === 403) {\n let body: unknown;\n try {\n body = await response.clone().json();\n } catch {\n // not JSON\n }\n const captchaUrl = (body as RawObj)?.url;\n if (typeof captchaUrl === 'string' && captchaUrl.includes('datadome')) {\n throw new DatadomeCaptcha(captchaUrl);\n }\n }\n\n return response;\n }\n\n private async _errorBody(response: Response): Promise<string> {\n try {\n return await response.clone().text();\n } catch {\n return '';\n }\n }\n\n // ---------------------------------------------------------------------------\n // Authentication\n // ---------------------------------------------------------------------------\n\n async loginWithPassword(password: string): Promise<void> {\n const url = `${this.globalConfig.endpoints.ssoEndpoint}/v1/user/login`;\n const response = await this._request('POST', url, {\n body: JSON.stringify({ user_name: this._username, password }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new LoginError(response.status, 'Failed to login with password.', body);\n }\n\n // The coulomb_sess cookie is set by the SSO endpoint on success;\n // _request() already extracted it from Set-Cookie above.\n await response.text(); // drain body\n\n if (!this._coulombToken) {\n throw new LoginError(response.status, 'Login succeeded but no session token was returned.');\n }\n }\n\n async loginWithSsoSession(ssoJwt: string): Promise<void> {\n // Exchange an SSO JWT for a coulomb_sess cookie via the portal endpoint.\n const url = `${this.globalConfig.endpoints.portalDomainEndpoint}/index.php/nghelper/getSession`;\n const response = await this._request('GET', url, {\n headers: {\n cookie: `auth-session=${ssoJwt}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new LoginError(response.status, 'Failed to login with SSO session.', body);\n }\n\n await response.text();\n }\n\n async logout(): Promise<void> {\n const url = `${this.globalConfig.endpoints.ssoEndpoint}/v1/user/logout`;\n try {\n await this._request('POST', url);\n } finally {\n this._coulombToken = null;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Account\n // ---------------------------------------------------------------------------\n\n async getAccount(): Promise<Account> {\n const url = `${this.globalConfig.endpoints.accountsEndpoint}/v1/driver/profile/user`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get account information.');\n }\n\n const data = (await response.json()) as Account;\n if (data.user?.userId) {\n this._userId = data.user.userId;\n }\n return data;\n }\n\n async getVehicles(): Promise<ElectricVehicle[]> {\n const url = `${this.globalConfig.endpoints.accountsEndpoint}/v1/driver/vehicle`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get vehicles.');\n }\n\n const data = (await response.json()) as RawObj;\n return (Array.isArray(data.vehicles) ? data.vehicles : []) as ElectricVehicle[];\n }\n\n async getUserChargingStatus(): Promise<UserChargingStatus | null> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v2`;\n const response = await this._request('POST', url, {\n body: JSON.stringify({ user_status: { timestamp: Date.now() } }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get user charging status.');\n }\n\n const data = (await response.json()) as RawObj;\n const userStatus = data.user_status as RawObj | null | undefined;\n\n if (!userStatus) return null;\n\n const charging = userStatus.charging_status as RawObj | null | undefined;\n if (!charging) return null;\n\n const stations: Station[] = Array.isArray(charging.stations)\n ? (charging.stations as RawObj[]).map((s) => ({\n id: s.id as number,\n name: typeof s.name === 'string' ? s.name : '',\n latitude: typeof s.lat === 'number' ? s.lat : (s.latitude as number ?? 0),\n longitude: typeof s.lon === 'number' ? s.lon : (s.longitude as number ?? 0),\n }))\n : [];\n\n return {\n sessionId: charging.session_id as number,\n startTime: parseMsTimestamp(charging.start_time),\n state: typeof charging.current_charging === 'string' ? charging.current_charging : '',\n stations,\n };\n }\n\n // ---------------------------------------------------------------------------\n // Home charger helpers\n // ---------------------------------------------------------------------------\n\n private async ensureUserId(): Promise<number> {\n if (this._userId !== null) return this._userId;\n const account = await this.getAccount();\n return account.user.userId;\n }\n\n async getHomeChargers(): Promise<number[]> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new CommunicationError(response.status, 'Failed to get home chargers.', body);\n }\n\n const data = (await response.json()) as RawObj;\n // API returns { data: [...] }; older shape used { chargers: [...] }\n const arr = Array.isArray(data.data)\n ? (data.data as RawObj[])\n : Array.isArray(data.chargers)\n ? (data.chargers as RawObj[])\n : [];\n return arr.map((c) => {\n // API uses \"id\" (string); older shape used chargerId / charger_id (number)\n const id = c.id ?? c.chargerId ?? c.charger_id;\n return typeof id === 'number' ? id : Number(id);\n });\n }\n\n async getHomeChargerStatus(chargerId: number): Promise<HomeChargerStatus> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/status`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger status.');\n }\n\n const data = (await response.json()) as RawObj;\n // Real API nests amperage info under chargeAmperageSettings; fall back to flat fields for older shapes\n const amp = (data.chargeAmperageSettings ?? {}) as RawObj;\n return {\n chargerId, // not echoed by the API; inject from parameter\n brand: String(data.brand ?? ''),\n model: String(data.model ?? ''),\n macAddress: String(data.macAddress ?? ''),\n chargingStatus: String(data.chargingStatus ?? ''),\n isPluggedIn: Boolean(data.isPluggedIn),\n isConnected: Boolean(data.isConnected),\n isReminderEnabled: Boolean(data.isReminderEnabled),\n plugInReminderTime: String(data.plugInReminderTime ?? ''),\n hasUtilityInfo: Boolean(data.hasUtilityInfo),\n isDuringScheduledTime: Boolean(data.isDuringScheduledTime),\n amperageLimit: Number(amp.chargeLimit ?? data.amperageLimit ?? 0),\n possibleAmperageLimits: ((amp.possibleChargeLimit ?? data.possibleAmperageLimits ?? []) as number[]).map(Number),\n };\n }\n\n async getHomeChargerTechnicalInfo(chargerId: number): Promise<HomeChargerTechnicalInfo> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/technical-info`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger technical info.');\n }\n\n return (await response.json()) as HomeChargerTechnicalInfo;\n }\n\n async getHomeChargerConfig(chargerId: number): Promise<HomeChargerConfiguration> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/configurations`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger configuration.');\n }\n\n const data = (await response.json()) as RawObj;\n // Real API wraps all fields under \"settings\"; fall back to flat shape for older responses\n const s = (data.settings ?? data) as RawObj;\n // LED brightness: real API uses settings.led.brightness with string-typed level/supportedLevels\n const rawLed = ((s.led as RawObj | undefined)?.brightness ?? s.ledBrightness ?? {}) as RawObj;\n const level =\n typeof rawLed.level === 'string'\n ? Number(rawLed.level)\n : Number(rawLed.level ?? rawLed.currentBrightnessSettings ?? 0);\n const supportedLevels = Array.isArray(rawLed.supportedLevels)\n ? (rawLed.supportedLevels as (string | number)[]).map(Number)\n : [];\n return {\n serialNumber: String(s.serialNumber ?? ''),\n macAddress: String(s.macAddress ?? ''),\n stationNickname: String(s.stationNickname ?? ''),\n streetAddress: String(s.streetAddress ?? ''),\n hasUtilityInfo: Boolean(s.hasUtilityInfo),\n utility: (s.utility ?? null) as HomeChargerConfiguration['utility'],\n // API may return boolean true/false or string \"ON\"/\"OFF\"\n indicatorLightEcoMode: s.indicatorLightEcoMode === true || s.indicatorLightEcoMode === 'ON',\n flashlightReset: Boolean(s.flashlightReset),\n worksWithNest: Boolean(s.worksWithNest),\n isPairedWithNest: Boolean(s.isPairedWithNest),\n isInstalledByInstaller: Boolean(s.isInstalledByInstaller),\n ledBrightness: {\n level,\n inProgress: Boolean(rawLed.inProgress),\n supportedLevels,\n isEnabled: rawLed.isEnabled !== false,\n },\n };\n }\n\n async getHomeChargerSchedule(chargerId: number): Promise<HomeChargerSchedule> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger schedule.');\n }\n\n return (await response.json()) as HomeChargerSchedule;\n }\n\n async setHomeChargerSchedule(\n chargerId: number,\n weekdayStart: string,\n weekdayEnd: string,\n weekendStart: string,\n weekendEnd: string,\n ): Promise<HomeChargerSchedule> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({\n schedule: {\n weekdays: { startTime: weekdayStart, endTime: weekdayEnd },\n weekends: { startTime: weekendStart, endTime: weekendEnd },\n },\n }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const body = await this._errorBody(response);\n throw new CommunicationError(response.status, `Failed to set home charger schedule. HTTP ${response.status}: ${body}`);\n }\n\n return (await response.json()) as HomeChargerSchedule;\n }\n\n async disableHomeChargerSchedule(chargerId: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({}),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to disable home charger schedule.');\n }\n\n await response.text();\n }\n\n async setAmperageLimit(chargerId: number, amperageLimit: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/charge-amperage-limit`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({ chargeAmperageLimit: amperageLimit }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const body = await this._errorBody(response);\n throw new CommunicationError(response.status, `Failed to set amperage limit. HTTP ${response.status}: ${body}`);\n }\n\n await response.text();\n }\n\n async setLedBrightness(chargerId: number, level: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/led-brightness`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({ ledBrightnessLevel: level }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const body = await this._errorBody(response);\n throw new CommunicationError(response.status, `Failed to set LED brightness. HTTP ${response.status}: ${body}`);\n }\n\n await response.text();\n }\n\n async restartHomeCharger(chargerId: number): Promise<void> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/restart`;\n const response = await this._request('POST', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to restart home charger.');\n }\n\n await response.text();\n }\n\n // ---------------------------------------------------------------------------\n // Charging sessions\n // ---------------------------------------------------------------------------\n\n async getChargingSession(sessionId: number): Promise<ChargingSession> {\n const session = new ChargingSession(sessionId);\n session._setClient(this);\n await session.refresh();\n return session;\n }\n\n async startChargingSession(deviceId: number): Promise<ChargingSession> {\n return ChargingSession.start(deviceId, this);\n }\n\n // ---------------------------------------------------------------------------\n // Stations\n // ---------------------------------------------------------------------------\n\n async getStation(deviceId: number): Promise<StationInfo> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v3/station/info?deviceId=${deviceId}&use_cache=false`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get station info.');\n }\n\n return (await response.json()) as StationInfo;\n }\n\n async getNearbyStations(bounds: ZoomBounds, filter: MapFilter = {}): Promise<MapStation[]> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v2`;\n const stationList: RawObj = {\n ne_lat: bounds.neLat,\n ne_lon: bounds.neLon,\n sw_lat: bounds.swLat,\n sw_lon: bounds.swLon,\n ...filter,\n };\n\n const response = await this._request('POST', url, {\n body: JSON.stringify({ station_list: stationList }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get nearby stations.');\n }\n\n const data = (await response.json()) as RawObj;\n const list = data.station_list as RawObj | undefined;\n return Array.isArray(list?.stations) ? (list.stations as MapStation[]) : [];\n }\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -149,8 +149,8 @@ interface HomeChargerSchedule {
|
|
|
149
149
|
hasUtilityInfo: boolean;
|
|
150
150
|
basedOnUtility: PowerUtility | null;
|
|
151
151
|
defaultSchedule: ChargeSchedule;
|
|
152
|
-
userSchedule
|
|
153
|
-
utilitySchedule
|
|
152
|
+
userSchedule?: ChargeSchedule;
|
|
153
|
+
utilitySchedule?: ChargeSchedule | null;
|
|
154
154
|
}
|
|
155
155
|
interface ChargingSessionUpdate {
|
|
156
156
|
energyKwh: number;
|
|
@@ -393,6 +393,7 @@ declare class ChargePoint {
|
|
|
393
393
|
private _setToken;
|
|
394
394
|
/** @internal Used by session.ts and tests. */
|
|
395
395
|
_request(method: string, url: string, init?: RequestInit): Promise<Response>;
|
|
396
|
+
private _errorBody;
|
|
396
397
|
loginWithPassword(password: string): Promise<void>;
|
|
397
398
|
loginWithSsoSession(ssoJwt: string): Promise<void>;
|
|
398
399
|
logout(): Promise<void>;
|
package/dist/index.d.ts
CHANGED
|
@@ -149,8 +149,8 @@ interface HomeChargerSchedule {
|
|
|
149
149
|
hasUtilityInfo: boolean;
|
|
150
150
|
basedOnUtility: PowerUtility | null;
|
|
151
151
|
defaultSchedule: ChargeSchedule;
|
|
152
|
-
userSchedule
|
|
153
|
-
utilitySchedule
|
|
152
|
+
userSchedule?: ChargeSchedule;
|
|
153
|
+
utilitySchedule?: ChargeSchedule | null;
|
|
154
154
|
}
|
|
155
155
|
interface ChargingSessionUpdate {
|
|
156
156
|
energyKwh: number;
|
|
@@ -393,6 +393,7 @@ declare class ChargePoint {
|
|
|
393
393
|
private _setToken;
|
|
394
394
|
/** @internal Used by session.ts and tests. */
|
|
395
395
|
_request(method: string, url: string, init?: RequestInit): Promise<Response>;
|
|
396
|
+
private _errorBody;
|
|
396
397
|
loginWithPassword(password: string): Promise<void>;
|
|
397
398
|
loginWithSsoSession(ssoJwt: string): Promise<void>;
|
|
398
399
|
logout(): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import https from 'https';
|
|
2
2
|
|
|
3
|
+
// package.json
|
|
4
|
+
var package_default = {
|
|
5
|
+
version: "0.3.5"};
|
|
6
|
+
|
|
3
7
|
// src/constants.ts
|
|
4
8
|
var DISCOVERY_API = "https://discovery.chargepoint.com/discovery/v3/globalconfig";
|
|
5
|
-
var VERSION =
|
|
9
|
+
var VERSION = package_default.version;
|
|
6
10
|
var USER_AGENT = `node-chargepoint/${VERSION}`;
|
|
7
11
|
|
|
8
12
|
// src/exceptions.ts
|
|
@@ -306,7 +310,12 @@ var ChargingSession = class _ChargingSession {
|
|
|
306
310
|
}
|
|
307
311
|
static async start(deviceId, client) {
|
|
308
312
|
await sendCommand(client, "start", deviceId);
|
|
309
|
-
const
|
|
313
|
+
const deadline = Date.now() + 15e3;
|
|
314
|
+
let status = await client.getUserChargingStatus();
|
|
315
|
+
while (!status && Date.now() < deadline) {
|
|
316
|
+
await sleep(2e3);
|
|
317
|
+
status = await client.getUserChargingStatus();
|
|
318
|
+
}
|
|
310
319
|
if (!status) {
|
|
311
320
|
throw new APIError("No active charging session found after start command.");
|
|
312
321
|
}
|
|
@@ -348,7 +357,7 @@ var ChargePoint = class _ChargePoint {
|
|
|
348
357
|
return client;
|
|
349
358
|
}
|
|
350
359
|
_setToken(token, region) {
|
|
351
|
-
this._coulombToken = token;
|
|
360
|
+
this._coulombToken = decodeURIComponent(token);
|
|
352
361
|
this._region = region;
|
|
353
362
|
}
|
|
354
363
|
/** @internal Used by session.ts and tests. */
|
|
@@ -369,7 +378,7 @@ var ChargePoint = class _ChargePoint {
|
|
|
369
378
|
for (const cookie of setCookies) {
|
|
370
379
|
const match = /^coulomb_sess=([^;]+)/.exec(cookie);
|
|
371
380
|
if (match) {
|
|
372
|
-
this._coulombToken = match[1] ??
|
|
381
|
+
this._coulombToken = decodeURIComponent(match[1] ?? "");
|
|
373
382
|
break;
|
|
374
383
|
}
|
|
375
384
|
}
|
|
@@ -389,6 +398,13 @@ var ChargePoint = class _ChargePoint {
|
|
|
389
398
|
}
|
|
390
399
|
return response;
|
|
391
400
|
}
|
|
401
|
+
async _errorBody(response) {
|
|
402
|
+
try {
|
|
403
|
+
return await response.clone().text();
|
|
404
|
+
} catch {
|
|
405
|
+
return "";
|
|
406
|
+
}
|
|
407
|
+
}
|
|
392
408
|
// ---------------------------------------------------------------------------
|
|
393
409
|
// Authentication
|
|
394
410
|
// ---------------------------------------------------------------------------
|
|
@@ -595,8 +611,7 @@ var ChargePoint = class _ChargePoint {
|
|
|
595
611
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;
|
|
596
612
|
const response = await this._request("PUT", url, {
|
|
597
613
|
body: JSON.stringify({
|
|
598
|
-
|
|
599
|
-
userSchedule: {
|
|
614
|
+
schedule: {
|
|
600
615
|
weekdays: { startTime: weekdayStart, endTime: weekdayEnd },
|
|
601
616
|
weekends: { startTime: weekendStart, endTime: weekendEnd }
|
|
602
617
|
}
|
|
@@ -604,14 +619,15 @@ var ChargePoint = class _ChargePoint {
|
|
|
604
619
|
headers: { "Content-Type": "application/json" }
|
|
605
620
|
});
|
|
606
621
|
if (!response.ok) {
|
|
607
|
-
|
|
622
|
+
const body = await this._errorBody(response);
|
|
623
|
+
throw new CommunicationError(response.status, `Failed to set home charger schedule. HTTP ${response.status}: ${body}`);
|
|
608
624
|
}
|
|
609
625
|
return await response.json();
|
|
610
626
|
}
|
|
611
627
|
async disableHomeChargerSchedule(chargerId) {
|
|
612
628
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;
|
|
613
629
|
const response = await this._request("PUT", url, {
|
|
614
|
-
body: JSON.stringify({
|
|
630
|
+
body: JSON.stringify({}),
|
|
615
631
|
headers: { "Content-Type": "application/json" }
|
|
616
632
|
});
|
|
617
633
|
if (!response.ok) {
|
|
@@ -622,22 +638,24 @@ var ChargePoint = class _ChargePoint {
|
|
|
622
638
|
async setAmperageLimit(chargerId, amperageLimit) {
|
|
623
639
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/charge-amperage-limit`;
|
|
624
640
|
const response = await this._request("PUT", url, {
|
|
625
|
-
body: JSON.stringify({ amperageLimit }),
|
|
641
|
+
body: JSON.stringify({ chargeAmperageLimit: amperageLimit }),
|
|
626
642
|
headers: { "Content-Type": "application/json" }
|
|
627
643
|
});
|
|
628
644
|
if (!response.ok) {
|
|
629
|
-
|
|
645
|
+
const body = await this._errorBody(response);
|
|
646
|
+
throw new CommunicationError(response.status, `Failed to set amperage limit. HTTP ${response.status}: ${body}`);
|
|
630
647
|
}
|
|
631
648
|
await response.text();
|
|
632
649
|
}
|
|
633
650
|
async setLedBrightness(chargerId, level) {
|
|
634
651
|
const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/led-brightness`;
|
|
635
652
|
const response = await this._request("PUT", url, {
|
|
636
|
-
body: JSON.stringify({ level }),
|
|
653
|
+
body: JSON.stringify({ ledBrightnessLevel: level }),
|
|
637
654
|
headers: { "Content-Type": "application/json" }
|
|
638
655
|
});
|
|
639
656
|
if (!response.ok) {
|
|
640
|
-
|
|
657
|
+
const body = await this._errorBody(response);
|
|
658
|
+
throw new CommunicationError(response.status, `Failed to set LED brightness. HTTP ${response.status}: ${body}`);
|
|
641
659
|
}
|
|
642
660
|
await response.text();
|
|
643
661
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/exceptions.ts","../src/global-config.ts","../src/session.ts","../src/client.ts"],"names":["parseMsTimestamp"],"mappings":"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","file":"index.js","sourcesContent":["export const DISCOVERY_API =\n 'https://discovery.chargepoint.com/discovery/v3/globalconfig';\n\nexport const VERSION = '0.0.1-alpha.0';\nexport const USER_AGENT = `node-chargepoint/${VERSION}`;\n","export class APIError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'APIError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class CommunicationError extends APIError {\n constructor(\n public readonly statusCode: number,\n message: string,\n public readonly body?: unknown,\n ) {\n super(message);\n this.name = 'CommunicationError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class LoginError extends CommunicationError {\n constructor(statusCode: number, message: string, body?: unknown) {\n super(statusCode, message, body);\n this.name = 'LoginError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class InvalidSession extends CommunicationError {\n constructor(statusCode = 401, message = 'ChargePoint session expired. Please log in again.', body?: unknown) {\n super(statusCode, message, body);\n this.name = 'InvalidSession';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class DatadomeCaptcha extends APIError {\n constructor(\n public readonly captchaUrl: string,\n message = 'Datadome captcha protection triggered.',\n ) {\n super(message);\n this.name = 'DatadomeCaptcha';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import https from 'node:https';\nimport { DISCOVERY_API, USER_AGENT } from './constants.js';\nimport { CommunicationError } from './exceptions.js';\nimport type { APIEndpoints, GlobalConfiguration } from './types.js';\n\ntype RawValue = Record<string, unknown>;\n\n// Node 24's built-in fetch automatically adds `Sec-Fetch-Mode: cors`, which\n// causes the ChargePoint discovery endpoint to return HTTP 500. Using node:https\n// directly avoids that header. Default import (not named) is required so that\n// MSW's runtime patch of https.request is visible at call time in unit tests.\nasync function postJson(url: string, body: string): Promise<{ status: number; data: RawValue }> {\n return new Promise((resolve, reject) => {\n const bodyBuf = Buffer.from(body, 'utf-8');\n const req = https.request(\n url,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Content-Length': bodyBuf.byteLength,\n 'User-Agent': USER_AGENT,\n },\n },\n (res) => {\n const chunks: Buffer[] = [];\n res.on('data', (chunk: Buffer) => chunks.push(chunk));\n res.on('end', () => {\n const statusCode = res.statusCode ?? 0;\n if (statusCode < 200 || statusCode >= 300) {\n reject(new CommunicationError(statusCode, 'Failed to fetch global configuration.'));\n return;\n }\n try {\n resolve({ status: statusCode, data: JSON.parse(Buffer.concat(chunks).toString('utf-8')) as RawValue });\n } catch {\n reject(new CommunicationError(statusCode, 'Failed to parse global configuration response.'));\n }\n });\n },\n );\n req.on('error', (err: Error) => {\n reject(new CommunicationError(0, `Failed to reach ChargePoint discovery API: ${err.message}`));\n });\n req.write(bodyBuf);\n req.end();\n });\n}\n\nfunction endpointStr(v: unknown): string {\n const raw =\n v !== null && typeof v === 'object' && 'value' in v\n ? String((v as RawValue).value ?? '')\n : typeof v === 'string'\n ? v\n : '';\n return raw.replace(/\\/+$/, ''); // strip trailing slashes so callers can always do `${url}/path`\n}\n\nfunction parseEndpoints(raw: RawValue): APIEndpoints {\n // Support both camelCase and snake_case keys from the discovery API\n const get = (camel: string, snake: string): string =>\n endpointStr(raw[camel] ?? raw[snake] ?? '');\n\n return {\n accountsEndpoint: get('accountsEndpoint', 'accounts_endpoint'),\n internalApiGatewayEndpoint: get('internalApiGatewayEndpoint', 'internal_api_gateway_endpoint'),\n mapcacheEndpoint: get('mapcacheEndpoint', 'mapcache_endpoint'),\n pandaWebsocketEndpoint: get('pandaWebsocketEndpoint', 'panda_websocket_endpoint'),\n paymentJavaEndpoint: get('paymentJavaEndpoint', 'payment_java_endpoint'),\n paymentPhpEndpoint: get('paymentPhpEndpoint', 'payment_php_endpoint'),\n portalDomainEndpoint: get('portalDomainEndpoint', 'portal_domain_endpoint'),\n portalSubdomain:\n typeof raw.portalSubdomain === 'string'\n ? raw.portalSubdomain\n : typeof raw.portal_subdomain === 'string'\n ? raw.portal_subdomain\n : '',\n ssoEndpoint: get('ssoEndpoint', 'sso_endpoint'),\n webservicesEndpoint: get('webservicesEndpoint', 'webservices_endpoint'),\n websocketEndpoint: get('websocketEndpoint', 'websocket_endpoint'),\n hcpoHcmEndpoint: get('hcpoHcmEndpoint', 'hcpo_hcm_endpoint'),\n };\n}\n\nexport async function fetchGlobalConfig(region = 'NA'): Promise<GlobalConfiguration> {\n const { data } = await postJson(DISCOVERY_API, JSON.stringify({ regionCode: region }));\n\n // The API may return the config directly or nested under \"globalConfiguration\"\n const raw = (typeof data.globalConfiguration === 'object' && data.globalConfiguration !== null\n ? data.globalConfiguration\n : data) as RawValue;\n\n const endpointsRaw = (raw.endPoints ?? raw.endpoints ?? {}) as RawValue;\n\n return {\n region: typeof raw.region === 'string' ? raw.region : region,\n defaultCountry: (raw.defaultCountry ?? {}) as GlobalConfiguration['defaultCountry'],\n supportedCountries: Array.isArray(raw.supportedCountries)\n ? (raw.supportedCountries as GlobalConfiguration['supportedCountries'])\n : [],\n defaultCurrency: (raw.currency ?? raw.defaultCurrency ?? {}) as GlobalConfiguration['defaultCurrency'],\n supportedCurrencies: Array.isArray(raw.supportedCurrencies)\n ? (raw.supportedCurrencies as GlobalConfiguration['supportedCurrencies'])\n : [],\n endpoints: parseEndpoints(endpointsRaw),\n };\n}\n","import type { ChargePoint } from './client.js';\nimport { APIError, CommunicationError } from './exceptions.js';\nimport type { ChargingSessionUpdate, PowerUtility, VehicleInfo } from './types.js';\n\nconst sleep = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\ntype RawObj = Record<string, unknown>;\n\nexport async function sendCommand(\n client: ChargePoint,\n action: 'start' | 'stop',\n deviceId: number,\n portNumber = 1,\n sessionId = 0,\n): Promise<void> {\n const actionPath = action === 'start' ? 'startsession' : 'stopSession';\n const body: RawObj = { deviceId };\n\n if (action === 'stop') {\n body.portNumber = portNumber;\n body.sessionId = sessionId;\n }\n\n const url = `${client.globalConfig.endpoints.accountsEndpoint}/v1/driver/station/${actionPath}`;\n const response = await client._request('POST', url, {\n body: JSON.stringify(body),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new CommunicationError(\n response.status,\n `Failed to ${action} ChargePoint session: ${text}`,\n );\n }\n\n const actionStatus = (await response.json()) as RawObj;\n const ackId = actionStatus.ackId;\n\n const ackUrl = `${client.globalConfig.endpoints.accountsEndpoint}/v1/driver/station/session/ack`;\n\n let lastStatus = 0;\n let errorMessage = `Session failed to ${action}.`;\n let errorBody: unknown;\n\n for (let attempt = 1; attempt <= 20; attempt++) {\n const ackResponse = await client._request('POST', ackUrl, {\n body: JSON.stringify({ ackId, action: `${action}_session` }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n lastStatus = ackResponse.status;\n\n if (ackResponse.status === 200) {\n return;\n }\n\n try {\n errorBody = await ackResponse.json();\n const msg = (errorBody as RawObj).errorMessage;\n if (typeof msg === 'string') errorMessage = msg;\n } catch {\n errorBody = undefined;\n }\n\n if (attempt < 20) {\n await sleep(3000);\n }\n }\n\n throw new CommunicationError(lastStatus, errorMessage, errorBody);\n}\n\nfunction parseMsTimestamp(v: unknown): Date {\n if (typeof v === 'number') return new Date(v);\n if (typeof v === 'string') return new Date(Number(v));\n return new Date(0);\n}\n\nfunction parseSessionUpdates(raw: unknown): ChargingSessionUpdate[] {\n if (!Array.isArray(raw)) return [];\n return raw.map((u: unknown) => {\n const item = u as RawObj;\n return {\n energyKwh: typeof item.energy_kwh === 'number' ? item.energy_kwh : 0,\n powerKw: typeof item.power_kw === 'number' ? item.power_kw : 0,\n timestamp: parseMsTimestamp(item.timestamp),\n };\n });\n}\n\nexport class ChargingSession {\n sessionId: number;\n deviceId = 0;\n deviceName = '';\n chargingState = '';\n chargingTime = 0;\n energyKwh = 0;\n milesAdded = 0;\n milesAddedPerHour = 0;\n outletNumber = 0;\n portLevel = 0;\n powerKw = 0;\n purpose = '';\n currencyIsoCode = '';\n paymentCompleted = false;\n paymentType = '';\n pricingSpecId = 0;\n totalAmount = 0;\n apiFlag = false;\n enableStopCharging = false;\n hasChargingReceipt = false;\n hasUtilityInfo = false;\n isHomeCharger = false;\n isPurposeFinalized = false;\n stopChargeSupported = false;\n companyId = 0;\n companyName = '';\n latitude = 0;\n longitude = 0;\n address = '';\n city = '';\n stateName = '';\n country = '';\n zipcode = '';\n updatePeriod = 0;\n startTime: Date | null = null;\n lastUpdateDataTimestamp: Date | null = null;\n updateData: ChargingSessionUpdate[] | null = null;\n utility: PowerUtility | null = null;\n vehicleInfo: VehicleInfo | null = null;\n\n private _client: ChargePoint | null = null;\n\n constructor(sessionId: number) {\n this.sessionId = sessionId;\n }\n\n /** @internal */\n _setClient(client: ChargePoint): void {\n this._client = client;\n }\n\n /** @internal Apply raw session data from the driver-bff API (snake_case keys). */\n _apply(data: RawObj): void {\n if (data.device_id !== undefined) this.deviceId = data.device_id as number;\n if (data.device_name !== undefined) this.deviceName = data.device_name as string;\n if (data.current_charging !== undefined) this.chargingState = data.current_charging as string;\n if (data.charging_time !== undefined) this.chargingTime = data.charging_time as number;\n if (data.energy_kwh !== undefined) this.energyKwh = data.energy_kwh as number;\n if (data.miles_added !== undefined) this.milesAdded = data.miles_added as number;\n if (data.miles_added_per_hour !== undefined) this.milesAddedPerHour = data.miles_added_per_hour as number;\n if (data.outlet_number !== undefined) this.outletNumber = data.outlet_number as number;\n if (data.port_level !== undefined) this.portLevel = data.port_level as number;\n if (data.power_kw !== undefined) this.powerKw = data.power_kw as number;\n if (data.purpose !== undefined) this.purpose = data.purpose as string;\n if (data.currency_iso_code !== undefined) this.currencyIsoCode = String(data.currency_iso_code);\n if (data.payment_completed !== undefined) this.paymentCompleted = data.payment_completed as boolean;\n if (data.payment_type !== undefined) this.paymentType = data.payment_type as string;\n if (data.pricing_spec_id !== undefined) this.pricingSpecId = data.pricing_spec_id as number;\n if (data.total_amount !== undefined) this.totalAmount = data.total_amount as number;\n if (data.api_flag !== undefined) this.apiFlag = data.api_flag as boolean;\n if (data.enable_stop_charging !== undefined) this.enableStopCharging = data.enable_stop_charging as boolean;\n if (data.has_charging_receipt !== undefined) this.hasChargingReceipt = data.has_charging_receipt as boolean;\n if (data.has_utility_info !== undefined) this.hasUtilityInfo = data.has_utility_info as boolean;\n if (data.is_home_charger !== undefined) this.isHomeCharger = data.is_home_charger as boolean;\n if (data.is_purpose_finalized !== undefined) this.isPurposeFinalized = data.is_purpose_finalized as boolean;\n if (data.stop_charge_supported !== undefined) this.stopChargeSupported = data.stop_charge_supported as boolean;\n if (data.company_id !== undefined) this.companyId = data.company_id as number;\n if (data.company_name !== undefined) this.companyName = data.company_name as string;\n if (data.lat !== undefined) this.latitude = data.lat as number;\n if (data.lon !== undefined) this.longitude = data.lon as number;\n if (data.address1 !== undefined) this.address = data.address1 as string;\n if (data.city !== undefined) this.city = data.city as string;\n if (data.state_name !== undefined) this.stateName = data.state_name as string;\n if (data.country !== undefined) this.country = data.country as string;\n if (data.zipcode !== undefined) this.zipcode = data.zipcode as string;\n if (data.update_period !== undefined) this.updatePeriod = data.update_period as number;\n if (data.start_time !== undefined) this.startTime = parseMsTimestamp(data.start_time);\n if (data.last_update_data_timestamp !== undefined) {\n this.lastUpdateDataTimestamp = parseMsTimestamp(data.last_update_data_timestamp);\n }\n if (data.update_data !== undefined) this.updateData = parseSessionUpdates(data.update_data);\n if (data.utility !== undefined) this.utility = (data.utility as PowerUtility) ?? null;\n if (data.vehicle_info !== undefined) this.vehicleInfo = (data.vehicle_info as VehicleInfo) ?? null;\n }\n\n async refresh(): Promise<void> {\n if (!this._client) throw new Error('ChargingSession client not set.');\n\n const url = `${this._client.globalConfig.endpoints.internalApiGatewayEndpoint}/driver-bff/v1/sessions/${this.sessionId}`;\n const response = await this._client._request('POST', url, {\n body: JSON.stringify({\n charging_status: { session_id: this.sessionId, mfhs: [] },\n }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get charging session data.');\n }\n\n const json = (await response.json()) as RawObj;\n const status = json.charging_status as RawObj | undefined;\n\n if (!status || 'error_message' in status || 'error' in status) {\n throw new CommunicationError(response.status, 'Failed to get charging session data.');\n }\n\n this._apply(status);\n }\n\n async stop(): Promise<void> {\n if (!this._client) throw new Error('ChargingSession client not set.');\n await sendCommand(\n this._client,\n 'stop',\n this.deviceId,\n this.outletNumber,\n this.sessionId,\n );\n }\n\n static async start(deviceId: number, client: ChargePoint): Promise<ChargingSession> {\n await sendCommand(client, 'start', deviceId);\n // The sessionId returned by the start endpoint is not the real session ID;\n // fetch it from the status API instead.\n const status = await client.getUserChargingStatus();\n if (!status) {\n throw new APIError('No active charging session found after start command.');\n }\n const session = new ChargingSession(status.sessionId);\n session._setClient(client);\n await session.refresh();\n return session;\n }\n}\n","import { USER_AGENT } from './constants.js';\nimport { CommunicationError, DatadomeCaptcha, InvalidSession, LoginError } from './exceptions.js';\nimport { fetchGlobalConfig } from './global-config.js';\nimport { ChargingSession } from './session.js';\nimport type {\n Account,\n ElectricVehicle,\n GlobalConfiguration,\n HomeChargerConfiguration,\n HomeChargerSchedule,\n HomeChargerStatus,\n HomeChargerTechnicalInfo,\n MapFilter,\n MapStation,\n Station,\n StationInfo,\n UserChargingStatus,\n ZoomBounds,\n} from './types.js';\n\ntype RawObj = Record<string, unknown>;\n\nexport interface ChargePointOptions {\n coulombToken?: string;\n region?: string;\n}\n\nfunction parseMsTimestamp(v: unknown): Date {\n if (typeof v === 'number') return new Date(v);\n if (typeof v === 'string') return new Date(Number(v));\n return new Date(0);\n}\n\nexport class ChargePoint {\n public globalConfig: GlobalConfiguration;\n private _username: string;\n private _coulombToken: string | null = null;\n private _region: string;\n private _userId: number | null = null;\n\n /** The current session token. Save this after login to avoid re-authenticating. */\n get coulombToken(): string | null {\n return this._coulombToken;\n }\n\n private constructor(username: string, globalConfig: GlobalConfiguration, region: string) {\n this._username = username;\n this.globalConfig = globalConfig;\n this._region = region;\n }\n\n static async create(username: string, options: ChargePointOptions = {}): Promise<ChargePoint> {\n const region = options.region ?? 'NA';\n const config = await fetchGlobalConfig(region);\n const client = new ChargePoint(username, config, region);\n\n if (options.coulombToken) {\n client._setToken(options.coulombToken, region);\n }\n\n return client;\n }\n\n private _setToken(token: string, region: string): void {\n this._coulombToken = token;\n this._region = region;\n }\n\n /** @internal Used by session.ts and tests. */\n async _request(method: string, url: string, init: RequestInit = {}): Promise<Response> {\n const headers = new Headers(init.headers as string[][] | Record<string, string> | Headers);\n headers.set('user-agent', USER_AGENT);\n\n if (!headers.has('content-type') && method !== 'GET') {\n headers.set('content-type', 'application/json');\n }\n\n if (this._coulombToken) {\n headers.set('cookie', `coulomb_sess=${this._coulombToken}`);\n headers.set('cp-session-type', 'CP_SESSION_TOKEN');\n headers.set('cp-session-token', this._coulombToken);\n headers.set('cp-region', this._region);\n }\n\n const response = await fetch(url, { ...init, method, headers });\n\n // Refresh coulomb_sess from Set-Cookie response header\n const setCookies: string[] =\n typeof (response.headers as unknown as { getSetCookie?: () => string[] }).getSetCookie ===\n 'function'\n ? (response.headers as unknown as { getSetCookie: () => string[] }).getSetCookie()\n : [response.headers.get('set-cookie') ?? ''].filter(Boolean);\n\n for (const cookie of setCookies) {\n const match = /^coulomb_sess=([^;]+)/.exec(cookie);\n if (match) {\n this._coulombToken = match[1] ?? null;\n break;\n }\n }\n\n if (response.status === 401) {\n throw new InvalidSession(401, 'ChargePoint session expired. Please log in again.');\n }\n\n if (response.status === 403) {\n let body: unknown;\n try {\n body = await response.clone().json();\n } catch {\n // not JSON\n }\n const captchaUrl = (body as RawObj)?.url;\n if (typeof captchaUrl === 'string' && captchaUrl.includes('datadome')) {\n throw new DatadomeCaptcha(captchaUrl);\n }\n }\n\n return response;\n }\n\n // ---------------------------------------------------------------------------\n // Authentication\n // ---------------------------------------------------------------------------\n\n async loginWithPassword(password: string): Promise<void> {\n const url = `${this.globalConfig.endpoints.ssoEndpoint}/v1/user/login`;\n const response = await this._request('POST', url, {\n body: JSON.stringify({ user_name: this._username, password }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new LoginError(response.status, 'Failed to login with password.', body);\n }\n\n // The coulomb_sess cookie is set by the SSO endpoint on success;\n // _request() already extracted it from Set-Cookie above.\n await response.text(); // drain body\n\n if (!this._coulombToken) {\n throw new LoginError(response.status, 'Login succeeded but no session token was returned.');\n }\n }\n\n async loginWithSsoSession(ssoJwt: string): Promise<void> {\n // Exchange an SSO JWT for a coulomb_sess cookie via the portal endpoint.\n const url = `${this.globalConfig.endpoints.portalDomainEndpoint}/index.php/nghelper/getSession`;\n const response = await this._request('GET', url, {\n headers: {\n cookie: `auth-session=${ssoJwt}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new LoginError(response.status, 'Failed to login with SSO session.', body);\n }\n\n await response.text();\n }\n\n async logout(): Promise<void> {\n const url = `${this.globalConfig.endpoints.ssoEndpoint}/v1/user/logout`;\n try {\n await this._request('POST', url);\n } finally {\n this._coulombToken = null;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Account\n // ---------------------------------------------------------------------------\n\n async getAccount(): Promise<Account> {\n const url = `${this.globalConfig.endpoints.accountsEndpoint}/v1/driver/profile/user`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get account information.');\n }\n\n const data = (await response.json()) as Account;\n if (data.user?.userId) {\n this._userId = data.user.userId;\n }\n return data;\n }\n\n async getVehicles(): Promise<ElectricVehicle[]> {\n const url = `${this.globalConfig.endpoints.accountsEndpoint}/v1/driver/vehicle`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get vehicles.');\n }\n\n const data = (await response.json()) as RawObj;\n return (Array.isArray(data.vehicles) ? data.vehicles : []) as ElectricVehicle[];\n }\n\n async getUserChargingStatus(): Promise<UserChargingStatus | null> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v2`;\n const response = await this._request('POST', url, {\n body: JSON.stringify({ user_status: { timestamp: Date.now() } }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get user charging status.');\n }\n\n const data = (await response.json()) as RawObj;\n const userStatus = data.user_status as RawObj | null | undefined;\n\n if (!userStatus) return null;\n\n const charging = userStatus.charging_status as RawObj | null | undefined;\n if (!charging) return null;\n\n const stations: Station[] = Array.isArray(charging.stations)\n ? (charging.stations as RawObj[]).map((s) => ({\n id: s.id as number,\n name: typeof s.name === 'string' ? s.name : '',\n latitude: typeof s.lat === 'number' ? s.lat : (s.latitude as number ?? 0),\n longitude: typeof s.lon === 'number' ? s.lon : (s.longitude as number ?? 0),\n }))\n : [];\n\n return {\n sessionId: charging.session_id as number,\n startTime: parseMsTimestamp(charging.start_time),\n state: typeof charging.current_charging === 'string' ? charging.current_charging : '',\n stations,\n };\n }\n\n // ---------------------------------------------------------------------------\n // Home charger helpers\n // ---------------------------------------------------------------------------\n\n private async ensureUserId(): Promise<number> {\n if (this._userId !== null) return this._userId;\n const account = await this.getAccount();\n return account.user.userId;\n }\n\n async getHomeChargers(): Promise<number[]> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new CommunicationError(response.status, 'Failed to get home chargers.', body);\n }\n\n const data = (await response.json()) as RawObj;\n // API returns { data: [...] }; older shape used { chargers: [...] }\n const arr = Array.isArray(data.data)\n ? (data.data as RawObj[])\n : Array.isArray(data.chargers)\n ? (data.chargers as RawObj[])\n : [];\n return arr.map((c) => {\n // API uses \"id\" (string); older shape used chargerId / charger_id (number)\n const id = c.id ?? c.chargerId ?? c.charger_id;\n return typeof id === 'number' ? id : Number(id);\n });\n }\n\n async getHomeChargerStatus(chargerId: number): Promise<HomeChargerStatus> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/status`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger status.');\n }\n\n const data = (await response.json()) as RawObj;\n // Real API nests amperage info under chargeAmperageSettings; fall back to flat fields for older shapes\n const amp = (data.chargeAmperageSettings ?? {}) as RawObj;\n return {\n chargerId, // not echoed by the API; inject from parameter\n brand: String(data.brand ?? ''),\n model: String(data.model ?? ''),\n macAddress: String(data.macAddress ?? ''),\n chargingStatus: String(data.chargingStatus ?? ''),\n isPluggedIn: Boolean(data.isPluggedIn),\n isConnected: Boolean(data.isConnected),\n isReminderEnabled: Boolean(data.isReminderEnabled),\n plugInReminderTime: String(data.plugInReminderTime ?? ''),\n hasUtilityInfo: Boolean(data.hasUtilityInfo),\n isDuringScheduledTime: Boolean(data.isDuringScheduledTime),\n amperageLimit: Number(amp.chargeLimit ?? data.amperageLimit ?? 0),\n possibleAmperageLimits: ((amp.possibleChargeLimit ?? data.possibleAmperageLimits ?? []) as number[]).map(Number),\n };\n }\n\n async getHomeChargerTechnicalInfo(chargerId: number): Promise<HomeChargerTechnicalInfo> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/technical-info`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger technical info.');\n }\n\n return (await response.json()) as HomeChargerTechnicalInfo;\n }\n\n async getHomeChargerConfig(chargerId: number): Promise<HomeChargerConfiguration> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/configurations`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger configuration.');\n }\n\n const data = (await response.json()) as RawObj;\n // Real API wraps all fields under \"settings\"; fall back to flat shape for older responses\n const s = (data.settings ?? data) as RawObj;\n // LED brightness: real API uses settings.led.brightness with string-typed level/supportedLevels\n const rawLed = ((s.led as RawObj | undefined)?.brightness ?? s.ledBrightness ?? {}) as RawObj;\n const level =\n typeof rawLed.level === 'string'\n ? Number(rawLed.level)\n : Number(rawLed.level ?? rawLed.currentBrightnessSettings ?? 0);\n const supportedLevels = Array.isArray(rawLed.supportedLevels)\n ? (rawLed.supportedLevels as (string | number)[]).map(Number)\n : [];\n return {\n serialNumber: String(s.serialNumber ?? ''),\n macAddress: String(s.macAddress ?? ''),\n stationNickname: String(s.stationNickname ?? ''),\n streetAddress: String(s.streetAddress ?? ''),\n hasUtilityInfo: Boolean(s.hasUtilityInfo),\n utility: (s.utility ?? null) as HomeChargerConfiguration['utility'],\n // API may return boolean true/false or string \"ON\"/\"OFF\"\n indicatorLightEcoMode: s.indicatorLightEcoMode === true || s.indicatorLightEcoMode === 'ON',\n flashlightReset: Boolean(s.flashlightReset),\n worksWithNest: Boolean(s.worksWithNest),\n isPairedWithNest: Boolean(s.isPairedWithNest),\n isInstalledByInstaller: Boolean(s.isInstalledByInstaller),\n ledBrightness: {\n level,\n inProgress: Boolean(rawLed.inProgress),\n supportedLevels,\n isEnabled: rawLed.isEnabled !== false,\n },\n };\n }\n\n async getHomeChargerSchedule(chargerId: number): Promise<HomeChargerSchedule> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger schedule.');\n }\n\n return (await response.json()) as HomeChargerSchedule;\n }\n\n async setHomeChargerSchedule(\n chargerId: number,\n weekdayStart: string,\n weekdayEnd: string,\n weekendStart: string,\n weekendEnd: string,\n ): Promise<HomeChargerSchedule> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({\n scheduleEnabled: true,\n userSchedule: {\n weekdays: { startTime: weekdayStart, endTime: weekdayEnd },\n weekends: { startTime: weekendStart, endTime: weekendEnd },\n },\n }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to set home charger schedule.');\n }\n\n return (await response.json()) as HomeChargerSchedule;\n }\n\n async disableHomeChargerSchedule(chargerId: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({ scheduleEnabled: false }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to disable home charger schedule.');\n }\n\n await response.text();\n }\n\n async setAmperageLimit(chargerId: number, amperageLimit: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/charge-amperage-limit`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({ amperageLimit }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to set amperage limit.');\n }\n\n await response.text();\n }\n\n async setLedBrightness(chargerId: number, level: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/led-brightness`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({ level }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to set LED brightness.');\n }\n\n await response.text();\n }\n\n async restartHomeCharger(chargerId: number): Promise<void> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/restart`;\n const response = await this._request('POST', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to restart home charger.');\n }\n\n await response.text();\n }\n\n // ---------------------------------------------------------------------------\n // Charging sessions\n // ---------------------------------------------------------------------------\n\n async getChargingSession(sessionId: number): Promise<ChargingSession> {\n const session = new ChargingSession(sessionId);\n session._setClient(this);\n await session.refresh();\n return session;\n }\n\n async startChargingSession(deviceId: number): Promise<ChargingSession> {\n return ChargingSession.start(deviceId, this);\n }\n\n // ---------------------------------------------------------------------------\n // Stations\n // ---------------------------------------------------------------------------\n\n async getStation(deviceId: number): Promise<StationInfo> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v3/station/info?deviceId=${deviceId}&use_cache=false`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get station info.');\n }\n\n return (await response.json()) as StationInfo;\n }\n\n async getNearbyStations(bounds: ZoomBounds, filter: MapFilter = {}): Promise<MapStation[]> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v2`;\n const stationList: RawObj = {\n ne_lat: bounds.neLat,\n ne_lon: bounds.neLon,\n sw_lat: bounds.swLat,\n sw_lon: bounds.swLon,\n ...filter,\n };\n\n const response = await this._request('POST', url, {\n body: JSON.stringify({ station_list: stationList }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get nearby stations.');\n }\n\n const data = (await response.json()) as RawObj;\n const list = data.station_list as RawObj | undefined;\n return Array.isArray(list?.stations) ? (list.stations as MapStation[]) : [];\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/constants.ts","../src/exceptions.ts","../src/global-config.ts","../src/session.ts","../src/client.ts"],"names":["parseMsTimestamp"],"mappings":"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","file":"index.js","sourcesContent":["{\n \"name\": \"node-chargepoint\",\n \"version\": \"0.3.5\",\n \"description\": \"A Node.js/TypeScript wrapper for the ChargePoint EV charging network API. Based on python-chargepoint by Marc Billow.\",\n \"keywords\": [\n \"chargepoint\",\n \"ev\",\n \"electric-vehicle\",\n \"charging\",\n \"evse\"\n ],\n \"homepage\": \"https://github.com/musicbender/node-chargepoint\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/musicbender/node-chargepoint.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/musicbender/node-chargepoint/issues\"\n },\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n }\n }\n },\n \"bin\": {\n \"chargepoint\": \"./dist/cli.cjs\"\n },\n \"files\": [\n \"dist\",\n \"LICENSE\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"eslint src tests\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:e2e\": \"vitest run --config vitest.e2e.config.ts\",\n \"prepublishOnly\": \"pnpm build && pnpm typecheck\"\n },\n \"engines\": {\n \"node\": \">=24\"\n },\n \"packageManager\": \"pnpm@11.0.9+sha512.34ce82e6780233cf9cad8685029a8f81d2e06196c5a9bad98879f7424940c6817c4e4524fb7d38b8553ceed48b9758b8ebaf1abd3600c232c4c8cf7366086f38\",\n \"dependencies\": {\n \"commander\": \"^12.1.0\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^22.0.0\",\n \"eslint\": \"^10.3.0\",\n \"msw\": \"^2.7.0\",\n \"tsup\": \"^8.3.0\",\n \"typescript\": \"^5.8.0\",\n \"typescript-eslint\": \"^8.59.2\",\n \"vitest\": \"^2.1.0\"\n }\n}\n","import pkg from '../package.json' with { type: 'json' };\n\nexport const DISCOVERY_API =\n 'https://discovery.chargepoint.com/discovery/v3/globalconfig';\n\nexport const VERSION: string = pkg.version;\nexport const USER_AGENT = `node-chargepoint/${VERSION}`;\n","export class APIError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'APIError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class CommunicationError extends APIError {\n constructor(\n public readonly statusCode: number,\n message: string,\n public readonly body?: unknown,\n ) {\n super(message);\n this.name = 'CommunicationError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class LoginError extends CommunicationError {\n constructor(statusCode: number, message: string, body?: unknown) {\n super(statusCode, message, body);\n this.name = 'LoginError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class InvalidSession extends CommunicationError {\n constructor(statusCode = 401, message = 'ChargePoint session expired. Please log in again.', body?: unknown) {\n super(statusCode, message, body);\n this.name = 'InvalidSession';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class DatadomeCaptcha extends APIError {\n constructor(\n public readonly captchaUrl: string,\n message = 'Datadome captcha protection triggered.',\n ) {\n super(message);\n this.name = 'DatadomeCaptcha';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import https from 'node:https';\nimport { DISCOVERY_API, USER_AGENT } from './constants.js';\nimport { CommunicationError } from './exceptions.js';\nimport type { APIEndpoints, GlobalConfiguration } from './types.js';\n\ntype RawValue = Record<string, unknown>;\n\n// Node 24's built-in fetch automatically adds `Sec-Fetch-Mode: cors`, which\n// causes the ChargePoint discovery endpoint to return HTTP 500. Using node:https\n// directly avoids that header. Default import (not named) is required so that\n// MSW's runtime patch of https.request is visible at call time in unit tests.\nasync function postJson(url: string, body: string): Promise<{ status: number; data: RawValue }> {\n return new Promise((resolve, reject) => {\n const bodyBuf = Buffer.from(body, 'utf-8');\n const req = https.request(\n url,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Content-Length': bodyBuf.byteLength,\n 'User-Agent': USER_AGENT,\n },\n },\n (res) => {\n const chunks: Buffer[] = [];\n res.on('data', (chunk: Buffer) => chunks.push(chunk));\n res.on('end', () => {\n const statusCode = res.statusCode ?? 0;\n if (statusCode < 200 || statusCode >= 300) {\n reject(new CommunicationError(statusCode, 'Failed to fetch global configuration.'));\n return;\n }\n try {\n resolve({ status: statusCode, data: JSON.parse(Buffer.concat(chunks).toString('utf-8')) as RawValue });\n } catch {\n reject(new CommunicationError(statusCode, 'Failed to parse global configuration response.'));\n }\n });\n },\n );\n req.on('error', (err: Error) => {\n reject(new CommunicationError(0, `Failed to reach ChargePoint discovery API: ${err.message}`));\n });\n req.write(bodyBuf);\n req.end();\n });\n}\n\nfunction endpointStr(v: unknown): string {\n const raw =\n v !== null && typeof v === 'object' && 'value' in v\n ? String((v as RawValue).value ?? '')\n : typeof v === 'string'\n ? v\n : '';\n return raw.replace(/\\/+$/, ''); // strip trailing slashes so callers can always do `${url}/path`\n}\n\nfunction parseEndpoints(raw: RawValue): APIEndpoints {\n // Support both camelCase and snake_case keys from the discovery API\n const get = (camel: string, snake: string): string =>\n endpointStr(raw[camel] ?? raw[snake] ?? '');\n\n return {\n accountsEndpoint: get('accountsEndpoint', 'accounts_endpoint'),\n internalApiGatewayEndpoint: get('internalApiGatewayEndpoint', 'internal_api_gateway_endpoint'),\n mapcacheEndpoint: get('mapcacheEndpoint', 'mapcache_endpoint'),\n pandaWebsocketEndpoint: get('pandaWebsocketEndpoint', 'panda_websocket_endpoint'),\n paymentJavaEndpoint: get('paymentJavaEndpoint', 'payment_java_endpoint'),\n paymentPhpEndpoint: get('paymentPhpEndpoint', 'payment_php_endpoint'),\n portalDomainEndpoint: get('portalDomainEndpoint', 'portal_domain_endpoint'),\n portalSubdomain:\n typeof raw.portalSubdomain === 'string'\n ? raw.portalSubdomain\n : typeof raw.portal_subdomain === 'string'\n ? raw.portal_subdomain\n : '',\n ssoEndpoint: get('ssoEndpoint', 'sso_endpoint'),\n webservicesEndpoint: get('webservicesEndpoint', 'webservices_endpoint'),\n websocketEndpoint: get('websocketEndpoint', 'websocket_endpoint'),\n hcpoHcmEndpoint: get('hcpoHcmEndpoint', 'hcpo_hcm_endpoint'),\n };\n}\n\nexport async function fetchGlobalConfig(region = 'NA'): Promise<GlobalConfiguration> {\n const { data } = await postJson(DISCOVERY_API, JSON.stringify({ regionCode: region }));\n\n // The API may return the config directly or nested under \"globalConfiguration\"\n const raw = (typeof data.globalConfiguration === 'object' && data.globalConfiguration !== null\n ? data.globalConfiguration\n : data) as RawValue;\n\n const endpointsRaw = (raw.endPoints ?? raw.endpoints ?? {}) as RawValue;\n\n return {\n region: typeof raw.region === 'string' ? raw.region : region,\n defaultCountry: (raw.defaultCountry ?? {}) as GlobalConfiguration['defaultCountry'],\n supportedCountries: Array.isArray(raw.supportedCountries)\n ? (raw.supportedCountries as GlobalConfiguration['supportedCountries'])\n : [],\n defaultCurrency: (raw.currency ?? raw.defaultCurrency ?? {}) as GlobalConfiguration['defaultCurrency'],\n supportedCurrencies: Array.isArray(raw.supportedCurrencies)\n ? (raw.supportedCurrencies as GlobalConfiguration['supportedCurrencies'])\n : [],\n endpoints: parseEndpoints(endpointsRaw),\n };\n}\n","import type { ChargePoint } from './client.js';\nimport { APIError, CommunicationError } from './exceptions.js';\nimport type { ChargingSessionUpdate, PowerUtility, VehicleInfo } from './types.js';\n\nconst sleep = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\ntype RawObj = Record<string, unknown>;\n\nexport async function sendCommand(\n client: ChargePoint,\n action: 'start' | 'stop',\n deviceId: number,\n portNumber = 1,\n sessionId = 0,\n): Promise<void> {\n const actionPath = action === 'start' ? 'startsession' : 'stopSession';\n const body: RawObj = { deviceId };\n\n if (action === 'stop') {\n body.portNumber = portNumber;\n body.sessionId = sessionId;\n }\n\n const url = `${client.globalConfig.endpoints.accountsEndpoint}/v1/driver/station/${actionPath}`;\n const response = await client._request('POST', url, {\n body: JSON.stringify(body),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new CommunicationError(\n response.status,\n `Failed to ${action} ChargePoint session: ${text}`,\n );\n }\n\n const actionStatus = (await response.json()) as RawObj;\n const ackId = actionStatus.ackId;\n\n const ackUrl = `${client.globalConfig.endpoints.accountsEndpoint}/v1/driver/station/session/ack`;\n\n let lastStatus = 0;\n let errorMessage = `Session failed to ${action}.`;\n let errorBody: unknown;\n\n for (let attempt = 1; attempt <= 20; attempt++) {\n const ackResponse = await client._request('POST', ackUrl, {\n body: JSON.stringify({ ackId, action: `${action}_session` }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n lastStatus = ackResponse.status;\n\n if (ackResponse.status === 200) {\n return;\n }\n\n try {\n errorBody = await ackResponse.json();\n const msg = (errorBody as RawObj).errorMessage;\n if (typeof msg === 'string') errorMessage = msg;\n } catch {\n errorBody = undefined;\n }\n\n if (attempt < 20) {\n await sleep(3000);\n }\n }\n\n throw new CommunicationError(lastStatus, errorMessage, errorBody);\n}\n\nfunction parseMsTimestamp(v: unknown): Date {\n if (typeof v === 'number') return new Date(v);\n if (typeof v === 'string') return new Date(Number(v));\n return new Date(0);\n}\n\nfunction parseSessionUpdates(raw: unknown): ChargingSessionUpdate[] {\n if (!Array.isArray(raw)) return [];\n return raw.map((u: unknown) => {\n const item = u as RawObj;\n return {\n energyKwh: typeof item.energy_kwh === 'number' ? item.energy_kwh : 0,\n powerKw: typeof item.power_kw === 'number' ? item.power_kw : 0,\n timestamp: parseMsTimestamp(item.timestamp),\n };\n });\n}\n\nexport class ChargingSession {\n sessionId: number;\n deviceId = 0;\n deviceName = '';\n chargingState = '';\n chargingTime = 0;\n energyKwh = 0;\n milesAdded = 0;\n milesAddedPerHour = 0;\n outletNumber = 0;\n portLevel = 0;\n powerKw = 0;\n purpose = '';\n currencyIsoCode = '';\n paymentCompleted = false;\n paymentType = '';\n pricingSpecId = 0;\n totalAmount = 0;\n apiFlag = false;\n enableStopCharging = false;\n hasChargingReceipt = false;\n hasUtilityInfo = false;\n isHomeCharger = false;\n isPurposeFinalized = false;\n stopChargeSupported = false;\n companyId = 0;\n companyName = '';\n latitude = 0;\n longitude = 0;\n address = '';\n city = '';\n stateName = '';\n country = '';\n zipcode = '';\n updatePeriod = 0;\n startTime: Date | null = null;\n lastUpdateDataTimestamp: Date | null = null;\n updateData: ChargingSessionUpdate[] | null = null;\n utility: PowerUtility | null = null;\n vehicleInfo: VehicleInfo | null = null;\n\n private _client: ChargePoint | null = null;\n\n constructor(sessionId: number) {\n this.sessionId = sessionId;\n }\n\n /** @internal */\n _setClient(client: ChargePoint): void {\n this._client = client;\n }\n\n /** @internal Apply raw session data from the driver-bff API (snake_case keys). */\n _apply(data: RawObj): void {\n if (data.device_id !== undefined) this.deviceId = data.device_id as number;\n if (data.device_name !== undefined) this.deviceName = data.device_name as string;\n if (data.current_charging !== undefined) this.chargingState = data.current_charging as string;\n if (data.charging_time !== undefined) this.chargingTime = data.charging_time as number;\n if (data.energy_kwh !== undefined) this.energyKwh = data.energy_kwh as number;\n if (data.miles_added !== undefined) this.milesAdded = data.miles_added as number;\n if (data.miles_added_per_hour !== undefined) this.milesAddedPerHour = data.miles_added_per_hour as number;\n if (data.outlet_number !== undefined) this.outletNumber = data.outlet_number as number;\n if (data.port_level !== undefined) this.portLevel = data.port_level as number;\n if (data.power_kw !== undefined) this.powerKw = data.power_kw as number;\n if (data.purpose !== undefined) this.purpose = data.purpose as string;\n if (data.currency_iso_code !== undefined) this.currencyIsoCode = String(data.currency_iso_code);\n if (data.payment_completed !== undefined) this.paymentCompleted = data.payment_completed as boolean;\n if (data.payment_type !== undefined) this.paymentType = data.payment_type as string;\n if (data.pricing_spec_id !== undefined) this.pricingSpecId = data.pricing_spec_id as number;\n if (data.total_amount !== undefined) this.totalAmount = data.total_amount as number;\n if (data.api_flag !== undefined) this.apiFlag = data.api_flag as boolean;\n if (data.enable_stop_charging !== undefined) this.enableStopCharging = data.enable_stop_charging as boolean;\n if (data.has_charging_receipt !== undefined) this.hasChargingReceipt = data.has_charging_receipt as boolean;\n if (data.has_utility_info !== undefined) this.hasUtilityInfo = data.has_utility_info as boolean;\n if (data.is_home_charger !== undefined) this.isHomeCharger = data.is_home_charger as boolean;\n if (data.is_purpose_finalized !== undefined) this.isPurposeFinalized = data.is_purpose_finalized as boolean;\n if (data.stop_charge_supported !== undefined) this.stopChargeSupported = data.stop_charge_supported as boolean;\n if (data.company_id !== undefined) this.companyId = data.company_id as number;\n if (data.company_name !== undefined) this.companyName = data.company_name as string;\n if (data.lat !== undefined) this.latitude = data.lat as number;\n if (data.lon !== undefined) this.longitude = data.lon as number;\n if (data.address1 !== undefined) this.address = data.address1 as string;\n if (data.city !== undefined) this.city = data.city as string;\n if (data.state_name !== undefined) this.stateName = data.state_name as string;\n if (data.country !== undefined) this.country = data.country as string;\n if (data.zipcode !== undefined) this.zipcode = data.zipcode as string;\n if (data.update_period !== undefined) this.updatePeriod = data.update_period as number;\n if (data.start_time !== undefined) this.startTime = parseMsTimestamp(data.start_time);\n if (data.last_update_data_timestamp !== undefined) {\n this.lastUpdateDataTimestamp = parseMsTimestamp(data.last_update_data_timestamp);\n }\n if (data.update_data !== undefined) this.updateData = parseSessionUpdates(data.update_data);\n if (data.utility !== undefined) this.utility = (data.utility as PowerUtility) ?? null;\n if (data.vehicle_info !== undefined) this.vehicleInfo = (data.vehicle_info as VehicleInfo) ?? null;\n }\n\n async refresh(): Promise<void> {\n if (!this._client) throw new Error('ChargingSession client not set.');\n\n const url = `${this._client.globalConfig.endpoints.internalApiGatewayEndpoint}/driver-bff/v1/sessions/${this.sessionId}`;\n const response = await this._client._request('POST', url, {\n body: JSON.stringify({\n charging_status: { session_id: this.sessionId, mfhs: [] },\n }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get charging session data.');\n }\n\n const json = (await response.json()) as RawObj;\n const status = json.charging_status as RawObj | undefined;\n\n if (!status || 'error_message' in status || 'error' in status) {\n throw new CommunicationError(response.status, 'Failed to get charging session data.');\n }\n\n this._apply(status);\n }\n\n async stop(): Promise<void> {\n if (!this._client) throw new Error('ChargingSession client not set.');\n await sendCommand(\n this._client,\n 'stop',\n this.deviceId,\n this.outletNumber,\n this.sessionId,\n );\n }\n\n static async start(deviceId: number, client: ChargePoint): Promise<ChargingSession> {\n await sendCommand(client, 'start', deviceId);\n\n // The start ack confirms the cloud received the command, but the session\n // may take a moment to appear in the status API (same async IoT pattern\n // as amperage/LED changes). Poll until it shows up.\n const deadline = Date.now() + 15_000;\n let status = await client.getUserChargingStatus();\n while (!status && Date.now() < deadline) {\n await sleep(2000);\n status = await client.getUserChargingStatus();\n }\n\n if (!status) {\n throw new APIError('No active charging session found after start command.');\n }\n const session = new ChargingSession(status.sessionId);\n session._setClient(client);\n await session.refresh();\n return session;\n }\n}\n","import { USER_AGENT } from './constants.js';\nimport { CommunicationError, DatadomeCaptcha, InvalidSession, LoginError } from './exceptions.js';\nimport { fetchGlobalConfig } from './global-config.js';\nimport { ChargingSession } from './session.js';\nimport type {\n Account,\n ElectricVehicle,\n GlobalConfiguration,\n HomeChargerConfiguration,\n HomeChargerSchedule,\n HomeChargerStatus,\n HomeChargerTechnicalInfo,\n MapFilter,\n MapStation,\n Station,\n StationInfo,\n UserChargingStatus,\n ZoomBounds,\n} from './types.js';\n\ntype RawObj = Record<string, unknown>;\n\nexport interface ChargePointOptions {\n coulombToken?: string;\n region?: string;\n}\n\nfunction parseMsTimestamp(v: unknown): Date {\n if (typeof v === 'number') return new Date(v);\n if (typeof v === 'string') return new Date(Number(v));\n return new Date(0);\n}\n\nexport class ChargePoint {\n public globalConfig: GlobalConfiguration;\n private _username: string;\n private _coulombToken: string | null = null;\n private _region: string;\n private _userId: number | null = null;\n\n /** The current session token. Save this after login to avoid re-authenticating. */\n get coulombToken(): string | null {\n return this._coulombToken;\n }\n\n private constructor(username: string, globalConfig: GlobalConfiguration, region: string) {\n this._username = username;\n this.globalConfig = globalConfig;\n this._region = region;\n }\n\n static async create(username: string, options: ChargePointOptions = {}): Promise<ChargePoint> {\n const region = options.region ?? 'NA';\n const config = await fetchGlobalConfig(region);\n const client = new ChargePoint(username, config, region);\n\n if (options.coulombToken) {\n client._setToken(options.coulombToken, region);\n }\n\n return client;\n }\n\n private _setToken(token: string, region: string): void {\n this._coulombToken = decodeURIComponent(token);\n this._region = region;\n }\n\n /** @internal Used by session.ts and tests. */\n async _request(method: string, url: string, init: RequestInit = {}): Promise<Response> {\n const headers = new Headers(init.headers as string[][] | Record<string, string> | Headers);\n headers.set('user-agent', USER_AGENT);\n\n if (!headers.has('content-type') && method !== 'GET') {\n headers.set('content-type', 'application/json');\n }\n\n if (this._coulombToken) {\n headers.set('cookie', `coulomb_sess=${this._coulombToken}`);\n headers.set('cp-session-type', 'CP_SESSION_TOKEN');\n headers.set('cp-session-token', this._coulombToken);\n headers.set('cp-region', this._region);\n }\n\n const response = await fetch(url, { ...init, method, headers });\n\n // Refresh coulomb_sess from Set-Cookie response header\n const setCookies: string[] =\n typeof (response.headers as unknown as { getSetCookie?: () => string[] }).getSetCookie ===\n 'function'\n ? (response.headers as unknown as { getSetCookie: () => string[] }).getSetCookie()\n : [response.headers.get('set-cookie') ?? ''].filter(Boolean);\n\n for (const cookie of setCookies) {\n const match = /^coulomb_sess=([^;]+)/.exec(cookie);\n if (match) {\n this._coulombToken = decodeURIComponent(match[1] ?? '');\n break;\n }\n }\n\n if (response.status === 401) {\n throw new InvalidSession(401, 'ChargePoint session expired. Please log in again.');\n }\n\n if (response.status === 403) {\n let body: unknown;\n try {\n body = await response.clone().json();\n } catch {\n // not JSON\n }\n const captchaUrl = (body as RawObj)?.url;\n if (typeof captchaUrl === 'string' && captchaUrl.includes('datadome')) {\n throw new DatadomeCaptcha(captchaUrl);\n }\n }\n\n return response;\n }\n\n private async _errorBody(response: Response): Promise<string> {\n try {\n return await response.clone().text();\n } catch {\n return '';\n }\n }\n\n // ---------------------------------------------------------------------------\n // Authentication\n // ---------------------------------------------------------------------------\n\n async loginWithPassword(password: string): Promise<void> {\n const url = `${this.globalConfig.endpoints.ssoEndpoint}/v1/user/login`;\n const response = await this._request('POST', url, {\n body: JSON.stringify({ user_name: this._username, password }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new LoginError(response.status, 'Failed to login with password.', body);\n }\n\n // The coulomb_sess cookie is set by the SSO endpoint on success;\n // _request() already extracted it from Set-Cookie above.\n await response.text(); // drain body\n\n if (!this._coulombToken) {\n throw new LoginError(response.status, 'Login succeeded but no session token was returned.');\n }\n }\n\n async loginWithSsoSession(ssoJwt: string): Promise<void> {\n // Exchange an SSO JWT for a coulomb_sess cookie via the portal endpoint.\n const url = `${this.globalConfig.endpoints.portalDomainEndpoint}/index.php/nghelper/getSession`;\n const response = await this._request('GET', url, {\n headers: {\n cookie: `auth-session=${ssoJwt}`,\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new LoginError(response.status, 'Failed to login with SSO session.', body);\n }\n\n await response.text();\n }\n\n async logout(): Promise<void> {\n const url = `${this.globalConfig.endpoints.ssoEndpoint}/v1/user/logout`;\n try {\n await this._request('POST', url);\n } finally {\n this._coulombToken = null;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Account\n // ---------------------------------------------------------------------------\n\n async getAccount(): Promise<Account> {\n const url = `${this.globalConfig.endpoints.accountsEndpoint}/v1/driver/profile/user`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get account information.');\n }\n\n const data = (await response.json()) as Account;\n if (data.user?.userId) {\n this._userId = data.user.userId;\n }\n return data;\n }\n\n async getVehicles(): Promise<ElectricVehicle[]> {\n const url = `${this.globalConfig.endpoints.accountsEndpoint}/v1/driver/vehicle`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get vehicles.');\n }\n\n const data = (await response.json()) as RawObj;\n return (Array.isArray(data.vehicles) ? data.vehicles : []) as ElectricVehicle[];\n }\n\n async getUserChargingStatus(): Promise<UserChargingStatus | null> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v2`;\n const response = await this._request('POST', url, {\n body: JSON.stringify({ user_status: { timestamp: Date.now() } }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get user charging status.');\n }\n\n const data = (await response.json()) as RawObj;\n const userStatus = data.user_status as RawObj | null | undefined;\n\n if (!userStatus) return null;\n\n const charging = userStatus.charging_status as RawObj | null | undefined;\n if (!charging) return null;\n\n const stations: Station[] = Array.isArray(charging.stations)\n ? (charging.stations as RawObj[]).map((s) => ({\n id: s.id as number,\n name: typeof s.name === 'string' ? s.name : '',\n latitude: typeof s.lat === 'number' ? s.lat : (s.latitude as number ?? 0),\n longitude: typeof s.lon === 'number' ? s.lon : (s.longitude as number ?? 0),\n }))\n : [];\n\n return {\n sessionId: charging.session_id as number,\n startTime: parseMsTimestamp(charging.start_time),\n state: typeof charging.current_charging === 'string' ? charging.current_charging : '',\n stations,\n };\n }\n\n // ---------------------------------------------------------------------------\n // Home charger helpers\n // ---------------------------------------------------------------------------\n\n private async ensureUserId(): Promise<number> {\n if (this._userId !== null) return this._userId;\n const account = await this.getAccount();\n return account.user.userId;\n }\n\n async getHomeChargers(): Promise<number[]> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n let body: unknown;\n try { body = await response.json(); } catch { /* ignore */ }\n throw new CommunicationError(response.status, 'Failed to get home chargers.', body);\n }\n\n const data = (await response.json()) as RawObj;\n // API returns { data: [...] }; older shape used { chargers: [...] }\n const arr = Array.isArray(data.data)\n ? (data.data as RawObj[])\n : Array.isArray(data.chargers)\n ? (data.chargers as RawObj[])\n : [];\n return arr.map((c) => {\n // API uses \"id\" (string); older shape used chargerId / charger_id (number)\n const id = c.id ?? c.chargerId ?? c.charger_id;\n return typeof id === 'number' ? id : Number(id);\n });\n }\n\n async getHomeChargerStatus(chargerId: number): Promise<HomeChargerStatus> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/status`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger status.');\n }\n\n const data = (await response.json()) as RawObj;\n // Real API nests amperage info under chargeAmperageSettings; fall back to flat fields for older shapes\n const amp = (data.chargeAmperageSettings ?? {}) as RawObj;\n return {\n chargerId, // not echoed by the API; inject from parameter\n brand: String(data.brand ?? ''),\n model: String(data.model ?? ''),\n macAddress: String(data.macAddress ?? ''),\n chargingStatus: String(data.chargingStatus ?? ''),\n isPluggedIn: Boolean(data.isPluggedIn),\n isConnected: Boolean(data.isConnected),\n isReminderEnabled: Boolean(data.isReminderEnabled),\n plugInReminderTime: String(data.plugInReminderTime ?? ''),\n hasUtilityInfo: Boolean(data.hasUtilityInfo),\n isDuringScheduledTime: Boolean(data.isDuringScheduledTime),\n amperageLimit: Number(amp.chargeLimit ?? data.amperageLimit ?? 0),\n possibleAmperageLimits: ((amp.possibleChargeLimit ?? data.possibleAmperageLimits ?? []) as number[]).map(Number),\n };\n }\n\n async getHomeChargerTechnicalInfo(chargerId: number): Promise<HomeChargerTechnicalInfo> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/technical-info`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger technical info.');\n }\n\n return (await response.json()) as HomeChargerTechnicalInfo;\n }\n\n async getHomeChargerConfig(chargerId: number): Promise<HomeChargerConfiguration> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/configurations`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger configuration.');\n }\n\n const data = (await response.json()) as RawObj;\n // Real API wraps all fields under \"settings\"; fall back to flat shape for older responses\n const s = (data.settings ?? data) as RawObj;\n // LED brightness: real API uses settings.led.brightness with string-typed level/supportedLevels\n const rawLed = ((s.led as RawObj | undefined)?.brightness ?? s.ledBrightness ?? {}) as RawObj;\n const level =\n typeof rawLed.level === 'string'\n ? Number(rawLed.level)\n : Number(rawLed.level ?? rawLed.currentBrightnessSettings ?? 0);\n const supportedLevels = Array.isArray(rawLed.supportedLevels)\n ? (rawLed.supportedLevels as (string | number)[]).map(Number)\n : [];\n return {\n serialNumber: String(s.serialNumber ?? ''),\n macAddress: String(s.macAddress ?? ''),\n stationNickname: String(s.stationNickname ?? ''),\n streetAddress: String(s.streetAddress ?? ''),\n hasUtilityInfo: Boolean(s.hasUtilityInfo),\n utility: (s.utility ?? null) as HomeChargerConfiguration['utility'],\n // API may return boolean true/false or string \"ON\"/\"OFF\"\n indicatorLightEcoMode: s.indicatorLightEcoMode === true || s.indicatorLightEcoMode === 'ON',\n flashlightReset: Boolean(s.flashlightReset),\n worksWithNest: Boolean(s.worksWithNest),\n isPairedWithNest: Boolean(s.isPairedWithNest),\n isInstalledByInstaller: Boolean(s.isInstalledByInstaller),\n ledBrightness: {\n level,\n inProgress: Boolean(rawLed.inProgress),\n supportedLevels,\n isEnabled: rawLed.isEnabled !== false,\n },\n };\n }\n\n async getHomeChargerSchedule(chargerId: number): Promise<HomeChargerSchedule> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get home charger schedule.');\n }\n\n return (await response.json()) as HomeChargerSchedule;\n }\n\n async setHomeChargerSchedule(\n chargerId: number,\n weekdayStart: string,\n weekdayEnd: string,\n weekendStart: string,\n weekendEnd: string,\n ): Promise<HomeChargerSchedule> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({\n schedule: {\n weekdays: { startTime: weekdayStart, endTime: weekdayEnd },\n weekends: { startTime: weekendStart, endTime: weekendEnd },\n },\n }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const body = await this._errorBody(response);\n throw new CommunicationError(response.status, `Failed to set home charger schedule. HTTP ${response.status}: ${body}`);\n }\n\n return (await response.json()) as HomeChargerSchedule;\n }\n\n async disableHomeChargerSchedule(chargerId: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/schedule/charger/${chargerId}/schedule`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({}),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to disable home charger schedule.');\n }\n\n await response.text();\n }\n\n async setAmperageLimit(chargerId: number, amperageLimit: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/charge-amperage-limit`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({ chargeAmperageLimit: amperageLimit }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const body = await this._errorBody(response);\n throw new CommunicationError(response.status, `Failed to set amperage limit. HTTP ${response.status}: ${body}`);\n }\n\n await response.text();\n }\n\n async setLedBrightness(chargerId: number, level: number): Promise<void> {\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/chargers/${chargerId}/led-brightness`;\n const response = await this._request('PUT', url, {\n body: JSON.stringify({ ledBrightnessLevel: level }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n const body = await this._errorBody(response);\n throw new CommunicationError(response.status, `Failed to set LED brightness. HTTP ${response.status}: ${body}`);\n }\n\n await response.text();\n }\n\n async restartHomeCharger(chargerId: number): Promise<void> {\n const userId = await this.ensureUserId();\n const url = `${this.globalConfig.endpoints.hcpoHcmEndpoint}/api/v1/configuration/users/${userId}/chargers/${chargerId}/restart`;\n const response = await this._request('POST', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to restart home charger.');\n }\n\n await response.text();\n }\n\n // ---------------------------------------------------------------------------\n // Charging sessions\n // ---------------------------------------------------------------------------\n\n async getChargingSession(sessionId: number): Promise<ChargingSession> {\n const session = new ChargingSession(sessionId);\n session._setClient(this);\n await session.refresh();\n return session;\n }\n\n async startChargingSession(deviceId: number): Promise<ChargingSession> {\n return ChargingSession.start(deviceId, this);\n }\n\n // ---------------------------------------------------------------------------\n // Stations\n // ---------------------------------------------------------------------------\n\n async getStation(deviceId: number): Promise<StationInfo> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v3/station/info?deviceId=${deviceId}&use_cache=false`;\n const response = await this._request('GET', url);\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get station info.');\n }\n\n return (await response.json()) as StationInfo;\n }\n\n async getNearbyStations(bounds: ZoomBounds, filter: MapFilter = {}): Promise<MapStation[]> {\n const url = `${this.globalConfig.endpoints.mapcacheEndpoint}/v2`;\n const stationList: RawObj = {\n ne_lat: bounds.neLat,\n ne_lon: bounds.neLon,\n sw_lat: bounds.swLat,\n sw_lon: bounds.swLon,\n ...filter,\n };\n\n const response = await this._request('POST', url, {\n body: JSON.stringify({ station_list: stationList }),\n headers: { 'Content-Type': 'application/json' },\n });\n\n if (!response.ok) {\n throw new CommunicationError(response.status, 'Failed to get nearby stations.');\n }\n\n const data = (await response.json()) as RawObj;\n const list = data.station_list as RawObj | undefined;\n return Array.isArray(list?.stations) ? (list.stations as MapStation[]) : [];\n }\n}\n"]}
|
package/package.json
CHANGED