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 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 = "0.0.1-alpha.0";
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 status = await client.getUserChargingStatus();
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] ?? null;
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
- scheduleEnabled: true,
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
- throw new CommunicationError(response.status, "Failed to set home charger schedule.");
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({ scheduleEnabled: false }),
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
- throw new CommunicationError(response.status, "Failed to set amperage limit.");
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
- throw new CommunicationError(response.status, "Failed to set LED brightness.");
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 = "0.0.1-alpha.0";
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 status = await client.getUserChargingStatus();
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] ?? null;
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
- scheduleEnabled: true,
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
- throw new CommunicationError(response.status, "Failed to set home charger schedule.");
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({ scheduleEnabled: false }),
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
- throw new CommunicationError(response.status, "Failed to set amperage limit.");
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
- throw new CommunicationError(response.status, "Failed to set LED brightness.");
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
  }
@@ -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: ChargeSchedule;
153
- utilitySchedule: ChargeSchedule | null;
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: ChargeSchedule;
153
- utilitySchedule: ChargeSchedule | null;
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 = "0.0.1-alpha.0";
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 status = await client.getUserChargingStatus();
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] ?? null;
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
- scheduleEnabled: true,
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
- throw new CommunicationError(response.status, "Failed to set home charger schedule.");
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({ scheduleEnabled: false }),
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
- throw new CommunicationError(response.status, "Failed to set amperage limit.");
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
- throw new CommunicationError(response.status, "Failed to set LED brightness.");
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":";;;AAAA,IAAA,eAAA,GAAA;AAAA,EAEE,OAAA,EAAW,OAkEb,CAAA;;;AClEO,IAAM,aAAA,GACX,6DAAA;AAEK,IAAM,UAAkB,eAAA,CAAI,OAAA;AAC5B,IAAM,UAAA,GAAa,oBAAoB,OAAO,CAAA,CAAA;;;ACN9C,IAAM,QAAA,GAAN,cAAuB,KAAA,CAAM;AAAA,EAClC,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,UAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF;AAEO,IAAM,kBAAA,GAAN,cAAiC,QAAA,CAAS;AAAA,EAC/C,WAAA,CACkB,UAAA,EAChB,OAAA,EACgB,IAAA,EAChB;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAJG,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AAEA,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAGhB,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EAPkB,UAAA;AAAA,EAEA,IAAA;AAMpB;AAEO,IAAM,UAAA,GAAN,cAAyB,kBAAA,CAAmB;AAAA,EACjD,WAAA,CAAY,UAAA,EAAoB,OAAA,EAAiB,IAAA,EAAgB;AAC/D,IAAA,KAAA,CAAM,UAAA,EAAY,SAAS,IAAI,CAAA;AAC/B,IAAA,IAAA,CAAK,IAAA,GAAO,YAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF;AAEO,IAAM,cAAA,GAAN,cAA6B,kBAAA,CAAmB;AAAA,EACrD,WAAA,CAAY,UAAA,GAAa,GAAA,EAAK,OAAA,GAAU,qDAAqD,IAAA,EAAgB;AAC3G,IAAA,KAAA,CAAM,UAAA,EAAY,SAAS,IAAI,CAAA;AAC/B,IAAA,IAAA,CAAK,IAAA,GAAO,gBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF;AAEO,IAAM,eAAA,GAAN,cAA8B,QAAA,CAAS;AAAA,EAC5C,WAAA,CACkB,UAAA,EAChB,OAAA,GAAU,wCAAA,EACV;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAHG,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AAIhB,IAAA,IAAA,CAAK,IAAA,GAAO,iBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA,EANkB,UAAA;AAOpB;AClCA,eAAe,QAAA,CAAS,KAAa,IAAA,EAA2D;AAC9F,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,IAAA,CAAK,IAAA,EAAM,OAAO,CAAA;AACzC,IAAA,MAAM,MAAM,KAAA,CAAM,OAAA;AAAA,MAChB,GAAA;AAAA,MACA;AAAA,QACE,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,cAAA,EAAgB,kBAAA;AAAA,UAChB,kBAAkB,OAAA,CAAQ,UAAA;AAAA,UAC1B,YAAA,EAAc;AAAA;AAChB,OACF;AAAA,MACA,CAAC,GAAA,KAAQ;AACP,QAAA,MAAM,SAAmB,EAAC;AAC1B,QAAA,GAAA,CAAI,GAAG,MAAA,EAAQ,CAAC,UAAkB,MAAA,CAAO,IAAA,CAAK,KAAK,CAAC,CAAA;AACpD,QAAA,GAAA,CAAI,EAAA,CAAG,OAAO,MAAM;AAClB,UAAA,MAAM,UAAA,GAAa,IAAI,UAAA,IAAc,CAAA;AACrC,UAAA,IAAI,UAAA,GAAa,GAAA,IAAO,UAAA,IAAc,GAAA,EAAK;AACzC,YAAA,MAAA,CAAO,IAAI,kBAAA,CAAmB,UAAA,EAAY,uCAAuC,CAAC,CAAA;AAClF,YAAA;AAAA,UACF;AACA,UAAA,IAAI;AACF,YAAA,OAAA,CAAQ,EAAE,MAAA,EAAQ,UAAA,EAAY,IAAA,EAAM,KAAK,KAAA,CAAM,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA,CAAE,QAAA,CAAS,OAAO,CAAC,GAAe,CAAA;AAAA,UACvG,CAAA,CAAA,MAAQ;AACN,YAAA,MAAA,CAAO,IAAI,kBAAA,CAAmB,UAAA,EAAY,gDAAgD,CAAC,CAAA;AAAA,UAC7F;AAAA,QACF,CAAC,CAAA;AAAA,MACH;AAAA,KACF;AACA,IAAA,GAAA,CAAI,EAAA,CAAG,OAAA,EAAS,CAAC,GAAA,KAAe;AAC9B,MAAA,MAAA,CAAO,IAAI,kBAAA,CAAmB,CAAA,EAAG,8CAA8C,GAAA,CAAI,OAAO,EAAE,CAAC,CAAA;AAAA,IAC/F,CAAC,CAAA;AACD,IAAA,GAAA,CAAI,MAAM,OAAO,CAAA;AACjB,IAAA,GAAA,CAAI,GAAA,EAAI;AAAA,EACV,CAAC,CAAA;AACH;AAEA,SAAS,YAAY,CAAA,EAAoB;AACvC,EAAA,MAAM,MACJ,CAAA,KAAM,IAAA,IAAQ,OAAO,CAAA,KAAM,YAAY,OAAA,IAAW,CAAA,GAC9C,MAAA,CAAQ,CAAA,CAAe,SAAS,EAAE,CAAA,GAClC,OAAO,CAAA,KAAM,WACX,CAAA,GACA,EAAA;AACR,EAAA,OAAO,GAAA,CAAI,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AAC/B;AAEA,SAAS,eAAe,GAAA,EAA6B;AAEnD,EAAA,MAAM,GAAA,GAAM,CAAC,KAAA,EAAe,KAAA,KAC1B,WAAA,CAAY,GAAA,CAAI,KAAK,CAAA,IAAK,GAAA,CAAI,KAAK,CAAA,IAAK,EAAE,CAAA;AAE5C,EAAA,OAAO;AAAA,IACL,gBAAA,EAAkB,GAAA,CAAI,kBAAA,EAAoB,mBAAmB,CAAA;AAAA,IAC7D,0BAAA,EAA4B,GAAA,CAAI,4BAAA,EAA8B,+BAA+B,CAAA;AAAA,IAC7F,gBAAA,EAAkB,GAAA,CAAI,kBAAA,EAAoB,mBAAmB,CAAA;AAAA,IAC7D,sBAAA,EAAwB,GAAA,CAAI,wBAAA,EAA0B,0BAA0B,CAAA;AAAA,IAChF,mBAAA,EAAqB,GAAA,CAAI,qBAAA,EAAuB,uBAAuB,CAAA;AAAA,IACvE,kBAAA,EAAoB,GAAA,CAAI,oBAAA,EAAsB,sBAAsB,CAAA;AAAA,IACpE,oBAAA,EAAsB,GAAA,CAAI,sBAAA,EAAwB,wBAAwB,CAAA;AAAA,IAC1E,eAAA,EACE,OAAO,GAAA,CAAI,eAAA,KAAoB,QAAA,GAC3B,GAAA,CAAI,eAAA,GACJ,OAAO,GAAA,CAAI,gBAAA,KAAqB,QAAA,GAC9B,GAAA,CAAI,gBAAA,GACJ,EAAA;AAAA,IACR,WAAA,EAAa,GAAA,CAAI,aAAA,EAAe,cAAc,CAAA;AAAA,IAC9C,mBAAA,EAAqB,GAAA,CAAI,qBAAA,EAAuB,sBAAsB,CAAA;AAAA,IACtE,iBAAA,EAAmB,GAAA,CAAI,mBAAA,EAAqB,oBAAoB,CAAA;AAAA,IAChE,eAAA,EAAiB,GAAA,CAAI,iBAAA,EAAmB,mBAAmB;AAAA,GAC7D;AACF;AAEA,eAAsB,iBAAA,CAAkB,SAAS,IAAA,EAAoC;AACnF,EAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,QAAA,CAAS,aAAA,EAAe,IAAA,CAAK,SAAA,CAAU,EAAE,UAAA,EAAY,MAAA,EAAQ,CAAC,CAAA;AAGrF,EAAA,MAAM,GAAA,GAAO,OAAO,IAAA,CAAK,mBAAA,KAAwB,YAAY,IAAA,CAAK,mBAAA,KAAwB,IAAA,GACtF,IAAA,CAAK,mBAAA,GACL,IAAA;AAEJ,EAAA,MAAM,YAAA,GAAgB,GAAA,CAAI,SAAA,IAAa,GAAA,CAAI,aAAa,EAAC;AAEzD,EAAA,OAAO;AAAA,IACL,QAAQ,OAAO,GAAA,CAAI,MAAA,KAAW,QAAA,GAAW,IAAI,MAAA,GAAS,MAAA;AAAA,IACtD,cAAA,EAAiB,GAAA,CAAI,cAAA,IAAkB,EAAC;AAAA,IACxC,kBAAA,EAAoB,MAAM,OAAA,CAAQ,GAAA,CAAI,kBAAkB,CAAA,GACnD,GAAA,CAAI,qBACL,EAAC;AAAA,IACL,eAAA,EAAkB,GAAA,CAAI,QAAA,IAAY,GAAA,CAAI,mBAAmB,EAAC;AAAA,IAC1D,mBAAA,EAAqB,MAAM,OAAA,CAAQ,GAAA,CAAI,mBAAmB,CAAA,GACrD,GAAA,CAAI,sBACL,EAAC;AAAA,IACL,SAAA,EAAW,eAAe,YAAY;AAAA,GACxC;AACF;;;ACvGA,IAAM,KAAA,GAAQ,CAAC,EAAA,KACb,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AAIlD,eAAsB,YACpB,MAAA,EACA,MAAA,EACA,UACA,UAAA,GAAa,CAAA,EACb,YAAY,CAAA,EACG;AACf,EAAA,MAAM,UAAA,GAAa,MAAA,KAAW,OAAA,GAAU,cAAA,GAAiB,aAAA;AACzD,EAAA,MAAM,IAAA,GAAe,EAAE,QAAA,EAAS;AAEhC,EAAA,IAAI,WAAW,MAAA,EAAQ;AACrB,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAClB,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AAAA,EACnB;AAEA,EAAA,MAAM,MAAM,CAAA,EAAG,MAAA,CAAO,aAAa,SAAA,CAAU,gBAAgB,sBAAsB,UAAU,CAAA,CAAA;AAC7F,EAAA,MAAM,QAAA,GAAW,MAAM,MAAA,CAAO,QAAA,CAAS,QAAQ,GAAA,EAAK;AAAA,IAClD,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA;AAAA,IACzB,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,GAC/C,CAAA;AAED,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA,EAAK;AACjC,IAAA,MAAM,IAAI,kBAAA;AAAA,MACR,QAAA,CAAS,MAAA;AAAA,MACT,CAAA,UAAA,EAAa,MAAM,CAAA,sBAAA,EAAyB,IAAI,CAAA;AAAA,KAClD;AAAA,EACF;AAEA,EAAA,MAAM,YAAA,GAAgB,MAAM,QAAA,CAAS,IAAA,EAAK;AAC1C,EAAA,MAAM,QAAQ,YAAA,CAAa,KAAA;AAE3B,EAAA,MAAM,MAAA,GAAS,CAAA,EAAG,MAAA,CAAO,YAAA,CAAa,UAAU,gBAAgB,CAAA,8BAAA,CAAA;AAEhE,EAAA,IAAI,UAAA,GAAa,CAAA;AACjB,EAAA,IAAI,YAAA,GAAe,qBAAqB,MAAM,CAAA,CAAA,CAAA;AAC9C,EAAA,IAAI,SAAA;AAEJ,EAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,IAAW,EAAA,EAAI,OAAA,EAAA,EAAW;AAC9C,IAAA,MAAM,WAAA,GAAc,MAAM,MAAA,CAAO,QAAA,CAAS,QAAQ,MAAA,EAAQ;AAAA,MACxD,IAAA,EAAM,KAAK,SAAA,CAAU,EAAE,OAAO,MAAA,EAAQ,CAAA,EAAG,MAAM,CAAA,QAAA,CAAA,EAAY,CAAA;AAAA,MAC3D,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,KAC/C,CAAA;AAED,IAAA,UAAA,GAAa,WAAA,CAAY,MAAA;AAEzB,IAAA,IAAI,WAAA,CAAY,WAAW,GAAA,EAAK;AAC9B,MAAA;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,SAAA,GAAY,MAAM,YAAY,IAAA,EAAK;AACnC,MAAA,MAAM,MAAO,SAAA,CAAqB,YAAA;AAClC,MAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,EAAU,YAAA,GAAe,GAAA;AAAA,IAC9C,CAAA,CAAA,MAAQ;AACN,MAAA,SAAA,GAAY,MAAA;AAAA,IACd;AAEA,IAAA,IAAI,UAAU,EAAA,EAAI;AAChB,MAAA,MAAM,MAAM,GAAI,CAAA;AAAA,IAClB;AAAA,EACF;AAEA,EAAA,MAAM,IAAI,kBAAA,CAAmB,UAAA,EAAY,YAAA,EAAc,SAAS,CAAA;AAClE;AAEA,SAAS,iBAAiB,CAAA,EAAkB;AAC1C,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,IAAI,KAAK,CAAC,CAAA;AAC5C,EAAA,IAAI,OAAO,MAAM,QAAA,EAAU,OAAO,IAAI,IAAA,CAAK,MAAA,CAAO,CAAC,CAAC,CAAA;AACpD,EAAA,uBAAO,IAAI,KAAK,CAAC,CAAA;AACnB;AAEA,SAAS,oBAAoB,GAAA,EAAuC;AAClE,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,SAAU,EAAC;AACjC,EAAA,OAAO,GAAA,CAAI,GAAA,CAAI,CAAC,CAAA,KAAe;AAC7B,IAAA,MAAM,IAAA,GAAO,CAAA;AACb,IAAA,OAAO;AAAA,MACL,WAAW,OAAO,IAAA,CAAK,UAAA,KAAe,QAAA,GAAW,KAAK,UAAA,GAAa,CAAA;AAAA,MACnE,SAAS,OAAO,IAAA,CAAK,QAAA,KAAa,QAAA,GAAW,KAAK,QAAA,GAAW,CAAA;AAAA,MAC7D,SAAA,EAAW,gBAAA,CAAiB,IAAA,CAAK,SAAS;AAAA,KAC5C;AAAA,EACF,CAAC,CAAA;AACH;AAEO,IAAM,eAAA,GAAN,MAAM,gBAAA,CAAgB;AAAA,EAC3B,SAAA;AAAA,EACA,QAAA,GAAW,CAAA;AAAA,EACX,UAAA,GAAa,EAAA;AAAA,EACb,aAAA,GAAgB,EAAA;AAAA,EAChB,YAAA,GAAe,CAAA;AAAA,EACf,SAAA,GAAY,CAAA;AAAA,EACZ,UAAA,GAAa,CAAA;AAAA,EACb,iBAAA,GAAoB,CAAA;AAAA,EACpB,YAAA,GAAe,CAAA;AAAA,EACf,SAAA,GAAY,CAAA;AAAA,EACZ,OAAA,GAAU,CAAA;AAAA,EACV,OAAA,GAAU,EAAA;AAAA,EACV,eAAA,GAAkB,EAAA;AAAA,EAClB,gBAAA,GAAmB,KAAA;AAAA,EACnB,WAAA,GAAc,EAAA;AAAA,EACd,aAAA,GAAgB,CAAA;AAAA,EAChB,WAAA,GAAc,CAAA;AAAA,EACd,OAAA,GAAU,KAAA;AAAA,EACV,kBAAA,GAAqB,KAAA;AAAA,EACrB,kBAAA,GAAqB,KAAA;AAAA,EACrB,cAAA,GAAiB,KAAA;AAAA,EACjB,aAAA,GAAgB,KAAA;AAAA,EAChB,kBAAA,GAAqB,KAAA;AAAA,EACrB,mBAAA,GAAsB,KAAA;AAAA,EACtB,SAAA,GAAY,CAAA;AAAA,EACZ,WAAA,GAAc,EAAA;AAAA,EACd,QAAA,GAAW,CAAA;AAAA,EACX,SAAA,GAAY,CAAA;AAAA,EACZ,OAAA,GAAU,EAAA;AAAA,EACV,IAAA,GAAO,EAAA;AAAA,EACP,SAAA,GAAY,EAAA;AAAA,EACZ,OAAA,GAAU,EAAA;AAAA,EACV,OAAA,GAAU,EAAA;AAAA,EACV,YAAA,GAAe,CAAA;AAAA,EACf,SAAA,GAAyB,IAAA;AAAA,EACzB,uBAAA,GAAuC,IAAA;AAAA,EACvC,UAAA,GAA6C,IAAA;AAAA,EAC7C,OAAA,GAA+B,IAAA;AAAA,EAC/B,WAAA,GAAkC,IAAA;AAAA,EAE1B,OAAA,GAA8B,IAAA;AAAA,EAEtC,YAAY,SAAA,EAAmB;AAC7B,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AAAA,EACnB;AAAA;AAAA,EAGA,WAAW,MAAA,EAA2B;AACpC,IAAA,IAAA,CAAK,OAAA,GAAU,MAAA;AAAA,EACjB;AAAA;AAAA,EAGA,OAAO,IAAA,EAAoB;AACzB,IAAA,IAAI,IAAA,CAAK,SAAA,KAAc,MAAA,EAAW,IAAA,CAAK,WAAW,IAAA,CAAK,SAAA;AACvD,IAAA,IAAI,IAAA,CAAK,WAAA,KAAgB,MAAA,EAAW,IAAA,CAAK,aAAa,IAAA,CAAK,WAAA;AAC3D,IAAA,IAAI,IAAA,CAAK,gBAAA,KAAqB,MAAA,EAAW,IAAA,CAAK,gBAAgB,IAAA,CAAK,gBAAA;AACnE,IAAA,IAAI,IAAA,CAAK,aAAA,KAAkB,MAAA,EAAW,IAAA,CAAK,eAAe,IAAA,CAAK,aAAA;AAC/D,IAAA,IAAI,IAAA,CAAK,UAAA,KAAe,MAAA,EAAW,IAAA,CAAK,YAAY,IAAA,CAAK,UAAA;AACzD,IAAA,IAAI,IAAA,CAAK,WAAA,KAAgB,MAAA,EAAW,IAAA,CAAK,aAAa,IAAA,CAAK,WAAA;AAC3D,IAAA,IAAI,IAAA,CAAK,oBAAA,KAAyB,MAAA,EAAW,IAAA,CAAK,oBAAoB,IAAA,CAAK,oBAAA;AAC3E,IAAA,IAAI,IAAA,CAAK,aAAA,KAAkB,MAAA,EAAW,IAAA,CAAK,eAAe,IAAA,CAAK,aAAA;AAC/D,IAAA,IAAI,IAAA,CAAK,UAAA,KAAe,MAAA,EAAW,IAAA,CAAK,YAAY,IAAA,CAAK,UAAA;AACzD,IAAA,IAAI,IAAA,CAAK,QAAA,KAAa,MAAA,EAAW,IAAA,CAAK,UAAU,IAAA,CAAK,QAAA;AACrD,IAAA,IAAI,IAAA,CAAK,OAAA,KAAY,MAAA,EAAW,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA;AACpD,IAAA,IAAI,KAAK,iBAAA,KAAsB,MAAA,OAAgB,eAAA,GAAkB,MAAA,CAAO,KAAK,iBAAiB,CAAA;AAC9F,IAAA,IAAI,IAAA,CAAK,iBAAA,KAAsB,MAAA,EAAW,IAAA,CAAK,mBAAmB,IAAA,CAAK,iBAAA;AACvE,IAAA,IAAI,IAAA,CAAK,YAAA,KAAiB,MAAA,EAAW,IAAA,CAAK,cAAc,IAAA,CAAK,YAAA;AAC7D,IAAA,IAAI,IAAA,CAAK,eAAA,KAAoB,MAAA,EAAW,IAAA,CAAK,gBAAgB,IAAA,CAAK,eAAA;AAClE,IAAA,IAAI,IAAA,CAAK,YAAA,KAAiB,MAAA,EAAW,IAAA,CAAK,cAAc,IAAA,CAAK,YAAA;AAC7D,IAAA,IAAI,IAAA,CAAK,QAAA,KAAa,MAAA,EAAW,IAAA,CAAK,UAAU,IAAA,CAAK,QAAA;AACrD,IAAA,IAAI,IAAA,CAAK,oBAAA,KAAyB,MAAA,EAAW,IAAA,CAAK,qBAAqB,IAAA,CAAK,oBAAA;AAC5E,IAAA,IAAI,IAAA,CAAK,oBAAA,KAAyB,MAAA,EAAW,IAAA,CAAK,qBAAqB,IAAA,CAAK,oBAAA;AAC5E,IAAA,IAAI,IAAA,CAAK,gBAAA,KAAqB,MAAA,EAAW,IAAA,CAAK,iBAAiB,IAAA,CAAK,gBAAA;AACpE,IAAA,IAAI,IAAA,CAAK,eAAA,KAAoB,MAAA,EAAW,IAAA,CAAK,gBAAgB,IAAA,CAAK,eAAA;AAClE,IAAA,IAAI,IAAA,CAAK,oBAAA,KAAyB,MAAA,EAAW,IAAA,CAAK,qBAAqB,IAAA,CAAK,oBAAA;AAC5E,IAAA,IAAI,IAAA,CAAK,qBAAA,KAA0B,MAAA,EAAW,IAAA,CAAK,sBAAsB,IAAA,CAAK,qBAAA;AAC9E,IAAA,IAAI,IAAA,CAAK,UAAA,KAAe,MAAA,EAAW,IAAA,CAAK,YAAY,IAAA,CAAK,UAAA;AACzD,IAAA,IAAI,IAAA,CAAK,YAAA,KAAiB,MAAA,EAAW,IAAA,CAAK,cAAc,IAAA,CAAK,YAAA;AAC7D,IAAA,IAAI,IAAA,CAAK,GAAA,KAAQ,MAAA,EAAW,IAAA,CAAK,WAAW,IAAA,CAAK,GAAA;AACjD,IAAA,IAAI,IAAA,CAAK,GAAA,KAAQ,MAAA,EAAW,IAAA,CAAK,YAAY,IAAA,CAAK,GAAA;AAClD,IAAA,IAAI,IAAA,CAAK,QAAA,KAAa,MAAA,EAAW,IAAA,CAAK,UAAU,IAAA,CAAK,QAAA;AACrD,IAAA,IAAI,IAAA,CAAK,IAAA,KAAS,MAAA,EAAW,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AAC9C,IAAA,IAAI,IAAA,CAAK,UAAA,KAAe,MAAA,EAAW,IAAA,CAAK,YAAY,IAAA,CAAK,UAAA;AACzD,IAAA,IAAI,IAAA,CAAK,OAAA,KAAY,MAAA,EAAW,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA;AACpD,IAAA,IAAI,IAAA,CAAK,OAAA,KAAY,MAAA,EAAW,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA;AACpD,IAAA,IAAI,IAAA,CAAK,aAAA,KAAkB,MAAA,EAAW,IAAA,CAAK,eAAe,IAAA,CAAK,aAAA;AAC/D,IAAA,IAAI,KAAK,UAAA,KAAe,MAAA,OAAgB,SAAA,GAAY,gBAAA,CAAiB,KAAK,UAAU,CAAA;AACpF,IAAA,IAAI,IAAA,CAAK,+BAA+B,MAAA,EAAW;AACjD,MAAA,IAAA,CAAK,uBAAA,GAA0B,gBAAA,CAAiB,IAAA,CAAK,0BAA0B,CAAA;AAAA,IACjF;AACA,IAAA,IAAI,KAAK,WAAA,KAAgB,MAAA,OAAgB,UAAA,GAAa,mBAAA,CAAoB,KAAK,WAAW,CAAA;AAC1F,IAAA,IAAI,KAAK,OAAA,KAAY,MAAA,EAAW,IAAA,CAAK,OAAA,GAAW,KAAK,OAAA,IAA4B,IAAA;AACjF,IAAA,IAAI,KAAK,YAAA,KAAiB,MAAA,EAAW,IAAA,CAAK,WAAA,GAAe,KAAK,YAAA,IAAgC,IAAA;AAAA,EAChG;AAAA,EAEA,MAAM,OAAA,GAAyB;AAC7B,IAAA,IAAI,CAAC,IAAA,CAAK,OAAA,EAAS,MAAM,IAAI,MAAM,iCAAiC,CAAA;AAEpE,IAAA,MAAM,GAAA,GAAM,GAAG,IAAA,CAAK,OAAA,CAAQ,aAAa,SAAA,CAAU,0BAA0B,CAAA,wBAAA,EAA2B,IAAA,CAAK,SAAS,CAAA,CAAA;AACtH,IAAA,MAAM,WAAW,MAAM,IAAA,CAAK,OAAA,CAAQ,QAAA,CAAS,QAAQ,GAAA,EAAK;AAAA,MACxD,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,QACnB,iBAAiB,EAAE,UAAA,EAAY,KAAK,SAAA,EAAW,IAAA,EAAM,EAAC;AAAE,OACzD,CAAA;AAAA,MACD,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,KAC/C,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,kBAAA,CAAmB,QAAA,CAAS,MAAA,EAAQ,sCAAsC,CAAA;AAAA,IACtF;AAEA,IAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAClC,IAAA,MAAM,SAAS,IAAA,CAAK,eAAA;AAEpB,IAAA,IAAI,CAAC,MAAA,IAAU,eAAA,IAAmB,MAAA,IAAU,WAAW,MAAA,EAAQ;AAC7D,MAAA,MAAM,IAAI,kBAAA,CAAmB,QAAA,CAAS,MAAA,EAAQ,sCAAsC,CAAA;AAAA,IACtF;AAEA,IAAA,IAAA,CAAK,OAAO,MAAM,CAAA;AAAA,EACpB;AAAA,EAEA,MAAM,IAAA,GAAsB;AAC1B,IAAA,IAAI,CAAC,IAAA,CAAK,OAAA,EAAS,MAAM,IAAI,MAAM,iCAAiC,CAAA;AACpE,IAAA,MAAM,WAAA;AAAA,MACJ,IAAA,CAAK,OAAA;AAAA,MACL,MAAA;AAAA,MACA,IAAA,CAAK,QAAA;AAAA,MACL,IAAA,CAAK,YAAA;AAAA,MACL,IAAA,CAAK;AAAA,KACP;AAAA,EACF;AAAA,EAEA,aAAa,KAAA,CAAM,QAAA,EAAkB,MAAA,EAA+C;AAClF,IAAA,MAAM,WAAA,CAAY,MAAA,EAAQ,OAAA,EAAS,QAAQ,CAAA;AAK3C,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,GAAI,IAAA;AAC9B,IAAA,IAAI,MAAA,GAAS,MAAM,MAAA,CAAO,qBAAA,EAAsB;AAChD,IAAA,OAAO,CAAC,MAAA,IAAU,IAAA,CAAK,GAAA,KAAQ,QAAA,EAAU;AACvC,MAAA,MAAM,MAAM,GAAI,CAAA;AAChB,MAAA,MAAA,GAAS,MAAM,OAAO,qBAAA,EAAsB;AAAA,IAC9C;AAEA,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,IAAI,SAAS,uDAAuD,CAAA;AAAA,IAC5E;AACA,IAAA,MAAM,OAAA,GAAU,IAAI,gBAAA,CAAgB,MAAA,CAAO,SAAS,CAAA;AACpD,IAAA,OAAA,CAAQ,WAAW,MAAM,CAAA;AACzB,IAAA,MAAM,QAAQ,OAAA,EAAQ;AACtB,IAAA,OAAO,OAAA;AAAA,EACT;AACF;;;AC3NA,SAASA,kBAAiB,CAAA,EAAkB;AAC1C,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,IAAI,KAAK,CAAC,CAAA;AAC5C,EAAA,IAAI,OAAO,MAAM,QAAA,EAAU,OAAO,IAAI,IAAA,CAAK,MAAA,CAAO,CAAC,CAAC,CAAA;AACpD,EAAA,uBAAO,IAAI,KAAK,CAAC,CAAA;AACnB;AAEO,IAAM,WAAA,GAAN,MAAM,YAAA,CAAY;AAAA,EAChB,YAAA;AAAA,EACC,SAAA;AAAA,EACA,aAAA,GAA+B,IAAA;AAAA,EAC/B,OAAA;AAAA,EACA,OAAA,GAAyB,IAAA;AAAA;AAAA,EAGjC,IAAI,YAAA,GAA8B;AAChC,IAAA,OAAO,IAAA,CAAK,aAAA;AAAA,EACd;AAAA,EAEQ,WAAA,CAAY,QAAA,EAAkB,YAAA,EAAmC,MAAA,EAAgB;AACvF,IAAA,IAAA,CAAK,SAAA,GAAY,QAAA;AACjB,IAAA,IAAA,CAAK,YAAA,GAAe,YAAA;AACpB,IAAA,IAAA,CAAK,OAAA,GAAU,MAAA;AAAA,EACjB;AAAA,EAEA,aAAa,MAAA,CAAO,QAAA,EAAkB,OAAA,GAA8B,EAAC,EAAyB;AAC5F,IAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,IAAU,IAAA;AACjC,IAAA,MAAM,MAAA,GAAS,MAAM,iBAAA,CAAkB,MAAM,CAAA;AAC7C,IAAA,MAAM,MAAA,GAAS,IAAI,YAAA,CAAY,QAAA,EAAU,QAAQ,MAAM,CAAA;AAEvD,IAAA,IAAI,QAAQ,YAAA,EAAc;AACxB,MAAA,MAAA,CAAO,SAAA,CAAU,OAAA,CAAQ,YAAA,EAAc,MAAM,CAAA;AAAA,IAC/C;AAEA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEQ,SAAA,CAAU,OAAe,MAAA,EAAsB;AACrD,IAAA,IAAA,CAAK,aAAA,GAAgB,mBAAmB,KAAK,CAAA;AAC7C,IAAA,IAAA,CAAK,OAAA,GAAU,MAAA;AAAA,EACjB;AAAA;AAAA,EAGA,MAAM,QAAA,CAAS,MAAA,EAAgB,GAAA,EAAa,IAAA,GAAoB,EAAC,EAAsB;AACrF,IAAA,MAAM,OAAA,GAAU,IAAI,OAAA,CAAQ,IAAA,CAAK,OAAwD,CAAA;AACzF,IAAA,OAAA,CAAQ,GAAA,CAAI,cAAc,UAAU,CAAA;AAEpC,IAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA,IAAK,WAAW,KAAA,EAAO;AACpD,MAAA,OAAA,CAAQ,GAAA,CAAI,gBAAgB,kBAAkB,CAAA;AAAA,IAChD;AAEA,IAAA,IAAI,KAAK,aAAA,EAAe;AACtB,MAAA,OAAA,CAAQ,GAAA,CAAI,QAAA,EAAU,CAAA,aAAA,EAAgB,IAAA,CAAK,aAAa,CAAA,CAAE,CAAA;AAC1D,MAAA,OAAA,CAAQ,GAAA,CAAI,mBAAmB,kBAAkB,CAAA;AACjD,MAAA,OAAA,CAAQ,GAAA,CAAI,kBAAA,EAAoB,IAAA,CAAK,aAAa,CAAA;AAClD,MAAA,OAAA,CAAQ,GAAA,CAAI,WAAA,EAAa,IAAA,CAAK,OAAO,CAAA;AAAA,IACvC;AAEA,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK,EAAE,GAAG,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,CAAA;AAG9D,IAAA,MAAM,aACJ,OAAQ,QAAA,CAAS,QAAyD,YAAA,KAC1E,UAAA,GACK,SAAS,OAAA,CAAwD,YAAA,KAClE,CAAC,QAAA,CAAS,QAAQ,GAAA,CAAI,YAAY,KAAK,EAAE,CAAA,CAAE,OAAO,OAAO,CAAA;AAE/D,IAAA,KAAA,MAAW,UAAU,UAAA,EAAY;AAC/B,MAAA,MAAM,KAAA,GAAQ,uBAAA,CAAwB,IAAA,CAAK,MAAM,CAAA;AACjD,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,IAAA,CAAK,aAAA,GAAgB,kBAAA,CAAmB,KAAA,CAAM,CAAC,KAAK,EAAE,CAAA;AACtD,QAAA;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,QAAA,CAAS,WAAW,GAAA,EAAK;AAC3B,MAAA,MAAM,IAAI,cAAA,CAAe,GAAA,EAAK,mDAAmD,CAAA;AAAA,IACnF;AAEA,IAAA,IAAI,QAAA,CAAS,WAAW,GAAA,EAAK;AAC3B,MAAA,IAAI,IAAA;AACJ,MAAA,IAAI;AACF,QAAA,IAAA,GAAO,MAAM,QAAA,CAAS,KAAA,EAAM,CAAE,IAAA,EAAK;AAAA,MACrC,CAAA,CAAA,MAAQ;AAAA,MAER;AACA,MAAA,MAAM,aAAc,IAAA,EAAiB,GAAA;AACrC,MAAA,IAAI,OAAO,UAAA,KAAe,QAAA,IAAY,UAAA,CAAW,QAAA,CAAS,UAAU,CAAA,EAAG;AACrE,QAAA,MAAM,IAAI,gBAAgB,UAAU,CAAA;AAAA,MACtC;AAAA,IACF;AAEA,IAAA,OAAO,QAAA;AAAA,EACT;AAAA,EAEA,MAAc,WAAW,QAAA,EAAqC;AAC5D,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,QAAA,CAAS,KAAA,EAAM,CAAE,IAAA,EAAK;AAAA,IACrC,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,EAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,kBAAkB,QAAA,EAAiC;AACvD,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,YAAA,CAAa,UAAU,WAAW,CAAA,cAAA,CAAA;AACtD,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,QAAA,CAAS,QAAQ,GAAA,EAAK;AAAA,MAChD,IAAA,EAAM,KAAK,SAAA,CAAU,EAAE,WAAW,IAAA,CAAK,SAAA,EAAW,UAAU,CAAA;AAAA,MAC5D,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,KAC/C,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,IAAI,IAAA;AACJ,MAAA,IAAI;AAAE,QAAA,IAAA,GAAO,MAAM,SAAS,IAAA,EAAK;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAA,MAAe;AAC3D,MAAA,MAAM,IAAI,UAAA,CAAW,QAAA,CAAS,MAAA,EAAQ,kCAAkC,IAAI,CAAA;AAAA,IAC9E;AAIA,IAAA,MAAM,SAAS,IAAA,EAAK;AAEpB,IAAA,IAAI,CAAC,KAAK,aAAA,EAAe;AACvB,MAAA,MAAM,IAAI,UAAA,CAAW,QAAA,CAAS,MAAA,EAAQ,oDAAoD,CAAA;AAAA,IAC5F;AAAA,EACF;AAAA,EAEA,MAAM,oBAAoB,MAAA,EAA+B;AAEvD,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,YAAA,CAAa,UAAU,oBAAoB,CAAA,8BAAA,CAAA;AAC/D,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,QAAA,CAAS,OAAO,GAAA,EAAK;AAAA,MAC/C,OAAA,EAAS;AAAA,QACP,MAAA,EAAQ,gBAAgB,MAAM,CAAA,CAAA;AAAA,QAC9B,cAAA,EAAgB;AAAA;AAClB,KACD,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,IAAI,IAAA;AACJ,MAAA,IAAI;AAAE,QAAA,IAAA,GAAO,MAAM,SAAS,IAAA,EAAK;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAA,MAAe;AAC3D,MAAA,MAAM,IAAI,UAAA,CAAW,QAAA,CAAS,MAAA,EAAQ,qCAAqC,IAAI,CAAA;AAAA,IACjF;AAEA,IAAA,MAAM,SAAS,IAAA,EAAK;AAAA,EACtB;AAAA,EAEA,MAAM,MAAA,GAAwB;AAC5B,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,YAAA,CAAa,UAAU,WAAW,CAAA,eAAA,CAAA;AACtD,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,QAAA,CAAS,MAAA,EAAQ,GAAG,CAAA;AAAA,IACjC,CAAA,SAAE;AACA,MAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AAAA,IACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,UAAA,GAA+B;AACnC,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,YAAA,CAAa,UAAU,gBAAgB,CAAA,uBAAA,CAAA;AAC3D,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,QAAA,CAAS,OAAO,GAAG,CAAA;AAE/C,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,kBAAA,CAAmB,QAAA,CAAS,MAAA,EAAQ,oCAAoC,CAAA;AAAA,IACpF;AAEA,IAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAClC,IAAA,IAAI,IAAA,CAAK,MAAM,MAAA,EAAQ;AACrB,MAAA,IAAA,CAAK,OAAA,GAAU,KAAK,IAAA,CAAK,MAAA;AAAA,IAC3B;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,WAAA,GAA0C;AAC9C,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,YAAA,CAAa,UAAU,gBAAgB,CAAA,kBAAA,CAAA;AAC3D,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,QAAA,CAAS,OAAO,GAAG,CAAA;AAE/C,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,kBAAA,CAAmB,QAAA,CAAS,MAAA,EAAQ,yBAAyB,CAAA;AAAA,IACzE;AAEA,IAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAClC,IAAA,OAAQ,MAAM,OAAA,CAAQ,IAAA,CAAK,QAAQ,CAAA,GAAI,IAAA,CAAK,WAAW,EAAC;AAAA,EAC1D;AAAA,EAEA,MAAM,qBAAA,GAA4D;AAChE,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,YAAA,CAAa,UAAU,gBAAgB,CAAA,GAAA,CAAA;AAC3D,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,QAAA,CAAS,QAAQ,GAAA,EAAK;AAAA,MAChD,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,EAAE,WAAA,EAAa,EAAE,SAAA,EAAW,IAAA,CAAK,GAAA,EAAI,EAAE,EAAG,CAAA;AAAA,MAC/D,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,KAC/C,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,kBAAA,CAAmB,QAAA,CAAS,MAAA,EAAQ,qCAAqC,CAAA;AAAA,IACrF;AAEA,IAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAClC,IAAA,MAAM,aAAa,IAAA,CAAK,WAAA;AAExB,IAAA,IAAI,CAAC,YAAY,OAAO,IAAA;AAExB,IAAA,MAAM,WAAW,UAAA,CAAW,eAAA;AAC5B,IAAA,IAAI,CAAC,UAAU,OAAO,IAAA;AAEtB,IAAA,MAAM,QAAA,GAAsB,KAAA,CAAM,OAAA,CAAQ,QAAA,CAAS,QAAQ,IACtD,QAAA,CAAS,QAAA,CAAsB,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,MAC1C,IAAI,CAAA,CAAE,EAAA;AAAA,MACN,MAAM,OAAO,CAAA,CAAE,IAAA,KAAS,QAAA,GAAW,EAAE,IAAA,GAAO,EAAA;AAAA,MAC5C,QAAA,EAAU,OAAO,CAAA,CAAE,GAAA,KAAQ,WAAW,CAAA,CAAE,GAAA,GAAO,EAAE,QAAA,IAAsB,CAAA;AAAA,MACvE,SAAA,EAAW,OAAO,CAAA,CAAE,GAAA,KAAQ,WAAW,CAAA,CAAE,GAAA,GAAO,EAAE,SAAA,IAAuB;AAAA,KAC3E,CAAE,IACF,EAAC;AAEL,IAAA,OAAO;AAAA,MACL,WAAW,QAAA,CAAS,UAAA;AAAA,MACpB,SAAA,EAAWA,iBAAAA,CAAiB,QAAA,CAAS,UAAU,CAAA;AAAA,MAC/C,OAAO,OAAO,QAAA,CAAS,gBAAA,KAAqB,QAAA,GAAW,SAAS,gBAAA,GAAmB,EAAA;AAAA,MACnF;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,YAAA,GAAgC;AAC5C,IAAA,IAAI,IAAA,CAAK,OAAA,KAAY,IAAA,EAAM,OAAO,IAAA,CAAK,OAAA;AACvC,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,UAAA,EAAW;AACtC,IAAA,OAAO,QAAQ,IAAA,CAAK,MAAA;AAAA,EACtB;AAAA,EAEA,MAAM,eAAA,GAAqC;AACzC,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,YAAA,EAAa;AACvC,IAAA,MAAM,MAAM,CAAA,EAAG,IAAA,CAAK,aAAa,SAAA,CAAU,eAAe,+BAA+B,MAAM,CAAA,SAAA,CAAA;AAC/F,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,QAAA,CAAS,OAAO,GAAG,CAAA;AAE/C,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,IAAI,IAAA;AACJ,MAAA,IAAI;AAAE,QAAA,IAAA,GAAO,MAAM,SAAS,IAAA,EAAK;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAA,MAAe;AAC3D,MAAA,MAAM,IAAI,kBAAA,CAAmB,QAAA,CAAS,MAAA,EAAQ,gCAAgC,IAAI,CAAA;AAAA,IACpF;AAEA,IAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAElC,IAAA,MAAM,GAAA,GAAM,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA,GAC9B,IAAA,CAAK,IAAA,GACN,KAAA,CAAM,QAAQ,IAAA,CAAK,QAAQ,CAAA,GACxB,IAAA,CAAK,WACN,EAAC;AACP,IAAA,OAAO,GAAA,CAAI,GAAA,CAAI,CAAC,CAAA,KAAM;AAEpB,MAAA,MAAM,EAAA,GAAK,CAAA,CAAE,EAAA,IAAM,CAAA,CAAE,aAAa,CAAA,CAAE,UAAA;AACpC,MAAA,OAAO,OAAO,EAAA,KAAO,QAAA,GAAW,EAAA,GAAK,OAAO,EAAE,CAAA;AAAA,IAChD,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,qBAAqB,SAAA,EAA+C;AACxE,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,YAAA,EAAa;AACvC,IAAA,MAAM,GAAA,GAAM,GAAG,IAAA,CAAK,YAAA,CAAa,UAAU,eAAe,CAAA,4BAAA,EAA+B,MAAM,CAAA,UAAA,EAAa,SAAS,CAAA,OAAA,CAAA;AACrH,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,QAAA,CAAS,OAAO,GAAG,CAAA;AAE/C,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,kBAAA,CAAmB,QAAA,CAAS,MAAA,EAAQ,oCAAoC,CAAA;AAAA,IACpF;AAEA,IAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAElC,IAAA,MAAM,GAAA,GAAO,IAAA,CAAK,sBAAA,IAA0B,EAAC;AAC7C,IAAA,OAAO;AAAA,MACL,SAAA;AAAA;AAAA,MACA,KAAA,EAAO,MAAA,CAAO,IAAA,CAAK,KAAA,IAAS,EAAE,CAAA;AAAA,MAC9B,KAAA,EAAO,MAAA,CAAO,IAAA,CAAK,KAAA,IAAS,EAAE,CAAA;AAAA,MAC9B,UAAA,EAAY,MAAA,CAAO,IAAA,CAAK,UAAA,IAAc,EAAE,CAAA;AAAA,MACxC,cAAA,EAAgB,MAAA,CAAO,IAAA,CAAK,cAAA,IAAkB,EAAE,CAAA;AAAA,MAChD,WAAA,EAAa,OAAA,CAAQ,IAAA,CAAK,WAAW,CAAA;AAAA,MACrC,WAAA,EAAa,OAAA,CAAQ,IAAA,CAAK,WAAW,CAAA;AAAA,MACrC,iBAAA,EAAmB,OAAA,CAAQ,IAAA,CAAK,iBAAiB,CAAA;AAAA,MACjD,kBAAA,EAAoB,MAAA,CAAO,IAAA,CAAK,kBAAA,IAAsB,EAAE,CAAA;AAAA,MACxD,cAAA,EAAgB,OAAA,CAAQ,IAAA,CAAK,cAAc,CAAA;AAAA,MAC3C,qBAAA,EAAuB,OAAA,CAAQ,IAAA,CAAK,qBAAqB,CAAA;AAAA,MACzD,eAAe,MAAA,CAAO,GAAA,CAAI,WAAA,IAAe,IAAA,CAAK,iBAAiB,CAAC,CAAA;AAAA,MAChE,sBAAA,EAAA,CAA0B,IAAI,mBAAA,IAAuB,IAAA,CAAK,0BAA0B,EAAC,EAAgB,IAAI,MAAM;AAAA,KACjH;AAAA,EACF;AAAA,EAEA,MAAM,4BAA4B,SAAA,EAAsD;AACtF,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,YAAA,EAAa;AACvC,IAAA,MAAM,GAAA,GAAM,GAAG,IAAA,CAAK,YAAA,CAAa,UAAU,eAAe,CAAA,4BAAA,EAA+B,MAAM,CAAA,UAAA,EAAa,SAAS,CAAA,eAAA,CAAA;AACrH,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,QAAA,CAAS,OAAO,GAAG,CAAA;AAE/C,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,kBAAA,CAAmB,QAAA,CAAS,MAAA,EAAQ,4CAA4C,CAAA;AAAA,IAC5F;AAEA,IAAA,OAAQ,MAAM,SAAS,IAAA,EAAK;AAAA,EAC9B;AAAA,EAEA,MAAM,qBAAqB,SAAA,EAAsD;AAC/E,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,YAAA,EAAa;AACvC,IAAA,MAAM,GAAA,GAAM,GAAG,IAAA,CAAK,YAAA,CAAa,UAAU,eAAe,CAAA,4BAAA,EAA+B,MAAM,CAAA,UAAA,EAAa,SAAS,CAAA,eAAA,CAAA;AACrH,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,QAAA,CAAS,OAAO,GAAG,CAAA;AAE/C,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,kBAAA,CAAmB,QAAA,CAAS,MAAA,EAAQ,2CAA2C,CAAA;AAAA,IAC3F;AAEA,IAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAElC,IAAA,MAAM,CAAA,GAAK,KAAK,QAAA,IAAY,IAAA;AAE5B,IAAA,MAAM,SAAW,CAAA,CAAE,GAAA,EAA4B,UAAA,IAAc,CAAA,CAAE,iBAAiB,EAAC;AACjF,IAAA,MAAM,KAAA,GACJ,OAAO,MAAA,CAAO,KAAA,KAAU,WACpB,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA,GACnB,MAAA,CAAO,MAAA,CAAO,KAAA,IAAS,MAAA,CAAO,6BAA6B,CAAC,CAAA;AAClE,IAAA,MAAM,eAAA,GAAkB,KAAA,CAAM,OAAA,CAAQ,MAAA,CAAO,eAAe,CAAA,GACvD,MAAA,CAAO,eAAA,CAAwC,GAAA,CAAI,MAAM,CAAA,GAC1D,EAAC;AACL,IAAA,OAAO;AAAA,MACL,YAAA,EAAc,MAAA,CAAO,CAAA,CAAE,YAAA,IAAgB,EAAE,CAAA;AAAA,MACzC,UAAA,EAAY,MAAA,CAAO,CAAA,CAAE,UAAA,IAAc,EAAE,CAAA;AAAA,MACrC,eAAA,EAAiB,MAAA,CAAO,CAAA,CAAE,eAAA,IAAmB,EAAE,CAAA;AAAA,MAC/C,aAAA,EAAe,MAAA,CAAO,CAAA,CAAE,aAAA,IAAiB,EAAE,CAAA;AAAA,MAC3C,cAAA,EAAgB,OAAA,CAAQ,CAAA,CAAE,cAAc,CAAA;AAAA,MACxC,OAAA,EAAU,EAAE,OAAA,IAAW,IAAA;AAAA;AAAA,MAEvB,qBAAA,EAAuB,CAAA,CAAE,qBAAA,KAA0B,IAAA,IAAQ,EAAE,qBAAA,KAA0B,IAAA;AAAA,MACvF,eAAA,EAAiB,OAAA,CAAQ,CAAA,CAAE,eAAe,CAAA;AAAA,MAC1C,aAAA,EAAe,OAAA,CAAQ,CAAA,CAAE,aAAa,CAAA;AAAA,MACtC,gBAAA,EAAkB,OAAA,CAAQ,CAAA,CAAE,gBAAgB,CAAA;AAAA,MAC5C,sBAAA,EAAwB,OAAA,CAAQ,CAAA,CAAE,sBAAsB,CAAA;AAAA,MACxD,aAAA,EAAe;AAAA,QACb,KAAA;AAAA,QACA,UAAA,EAAY,OAAA,CAAQ,MAAA,CAAO,UAAU,CAAA;AAAA,QACrC,eAAA;AAAA,QACA,SAAA,EAAW,OAAO,SAAA,KAAc;AAAA;AAClC,KACF;AAAA,EACF;AAAA,EAEA,MAAM,uBAAuB,SAAA,EAAiD;AAC5E,IAAA,MAAM,MAAM,CAAA,EAAG,IAAA,CAAK,aAAa,SAAA,CAAU,eAAe,4BAA4B,SAAS,CAAA,SAAA,CAAA;AAC/F,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,QAAA,CAAS,OAAO,GAAG,CAAA;AAE/C,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,kBAAA,CAAmB,QAAA,CAAS,MAAA,EAAQ,sCAAsC,CAAA;AAAA,IACtF;AAEA,IAAA,OAAQ,MAAM,SAAS,IAAA,EAAK;AAAA,EAC9B;AAAA,EAEA,MAAM,sBAAA,CACJ,SAAA,EACA,YAAA,EACA,UAAA,EACA,cACA,UAAA,EAC8B;AAC9B,IAAA,MAAM,MAAM,CAAA,EAAG,IAAA,CAAK,aAAa,SAAA,CAAU,eAAe,4BAA4B,SAAS,CAAA,SAAA,CAAA;AAC/F,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,QAAA,CAAS,OAAO,GAAA,EAAK;AAAA,MAC/C,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,QACnB,QAAA,EAAU;AAAA,UACR,QAAA,EAAU,EAAE,SAAA,EAAW,YAAA,EAAc,SAAS,UAAA,EAAW;AAAA,UACzD,QAAA,EAAU,EAAE,SAAA,EAAW,YAAA,EAAc,SAAS,UAAA;AAAW;AAC3D,OACD,CAAA;AAAA,MACD,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,KAC/C,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,UAAA,CAAW,QAAQ,CAAA;AAC3C,MAAA,MAAM,IAAI,mBAAmB,QAAA,CAAS,MAAA,EAAQ,6CAA6C,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,IAAI,CAAA,CAAE,CAAA;AAAA,IACvH;AAEA,IAAA,OAAQ,MAAM,SAAS,IAAA,EAAK;AAAA,EAC9B;AAAA,EAEA,MAAM,2BAA2B,SAAA,EAAkC;AACjE,IAAA,MAAM,MAAM,CAAA,EAAG,IAAA,CAAK,aAAa,SAAA,CAAU,eAAe,4BAA4B,SAAS,CAAA,SAAA,CAAA;AAC/F,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,QAAA,CAAS,OAAO,GAAA,EAAK;AAAA,MAC/C,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,EAAE,CAAA;AAAA,MACvB,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,KAC/C,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,kBAAA,CAAmB,QAAA,CAAS,MAAA,EAAQ,0CAA0C,CAAA;AAAA,IAC1F;AAEA,IAAA,MAAM,SAAS,IAAA,EAAK;AAAA,EACtB;AAAA,EAEA,MAAM,gBAAA,CAAiB,SAAA,EAAmB,aAAA,EAAsC;AAC9E,IAAA,MAAM,MAAM,CAAA,EAAG,IAAA,CAAK,aAAa,SAAA,CAAU,eAAe,kCAAkC,SAAS,CAAA,sBAAA,CAAA;AACrG,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,QAAA,CAAS,OAAO,GAAA,EAAK;AAAA,MAC/C,MAAM,IAAA,CAAK,SAAA,CAAU,EAAE,mBAAA,EAAqB,eAAe,CAAA;AAAA,MAC3D,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,KAC/C,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,UAAA,CAAW,QAAQ,CAAA;AAC3C,MAAA,MAAM,IAAI,mBAAmB,QAAA,CAAS,MAAA,EAAQ,sCAAsC,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,IAAI,CAAA,CAAE,CAAA;AAAA,IAChH;AAEA,IAAA,MAAM,SAAS,IAAA,EAAK;AAAA,EACtB;AAAA,EAEA,MAAM,gBAAA,CAAiB,SAAA,EAAmB,KAAA,EAA8B;AACtE,IAAA,MAAM,MAAM,CAAA,EAAG,IAAA,CAAK,aAAa,SAAA,CAAU,eAAe,kCAAkC,SAAS,CAAA,eAAA,CAAA;AACrG,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,QAAA,CAAS,OAAO,GAAA,EAAK;AAAA,MAC/C,MAAM,IAAA,CAAK,SAAA,CAAU,EAAE,kBAAA,EAAoB,OAAO,CAAA;AAAA,MAClD,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,KAC/C,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,UAAA,CAAW,QAAQ,CAAA;AAC3C,MAAA,MAAM,IAAI,mBAAmB,QAAA,CAAS,MAAA,EAAQ,sCAAsC,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,IAAI,CAAA,CAAE,CAAA;AAAA,IAChH;AAEA,IAAA,MAAM,SAAS,IAAA,EAAK;AAAA,EACtB;AAAA,EAEA,MAAM,mBAAmB,SAAA,EAAkC;AACzD,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,YAAA,EAAa;AACvC,IAAA,MAAM,GAAA,GAAM,GAAG,IAAA,CAAK,YAAA,CAAa,UAAU,eAAe,CAAA,4BAAA,EAA+B,MAAM,CAAA,UAAA,EAAa,SAAS,CAAA,QAAA,CAAA;AACrH,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,QAAA,CAAS,QAAQ,GAAG,CAAA;AAEhD,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,kBAAA,CAAmB,QAAA,CAAS,MAAA,EAAQ,iCAAiC,CAAA;AAAA,IACjF;AAEA,IAAA,MAAM,SAAS,IAAA,EAAK;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,mBAAmB,SAAA,EAA6C;AACpE,IAAA,MAAM,OAAA,GAAU,IAAI,eAAA,CAAgB,SAAS,CAAA;AAC7C,IAAA,OAAA,CAAQ,WAAW,IAAI,CAAA;AACvB,IAAA,MAAM,QAAQ,OAAA,EAAQ;AACtB,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAM,qBAAqB,QAAA,EAA4C;AACrE,IAAA,OAAO,eAAA,CAAgB,KAAA,CAAM,QAAA,EAAU,IAAI,CAAA;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WAAW,QAAA,EAAwC;AACvD,IAAA,MAAM,MAAM,CAAA,EAAG,IAAA,CAAK,aAAa,SAAA,CAAU,gBAAgB,6BAA6B,QAAQ,CAAA,gBAAA,CAAA;AAChG,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,QAAA,CAAS,OAAO,GAAG,CAAA;AAE/C,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,kBAAA,CAAmB,QAAA,CAAS,MAAA,EAAQ,6BAA6B,CAAA;AAAA,IAC7E;AAEA,IAAA,OAAQ,MAAM,SAAS,IAAA,EAAK;AAAA,EAC9B;AAAA,EAEA,MAAM,iBAAA,CAAkB,MAAA,EAAoB,MAAA,GAAoB,EAAC,EAA0B;AACzF,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,YAAA,CAAa,UAAU,gBAAgB,CAAA,GAAA,CAAA;AAC3D,IAAA,MAAM,WAAA,GAAsB;AAAA,MAC1B,QAAQ,MAAA,CAAO,KAAA;AAAA,MACf,QAAQ,MAAA,CAAO,KAAA;AAAA,MACf,QAAQ,MAAA,CAAO,KAAA;AAAA,MACf,QAAQ,MAAA,CAAO,KAAA;AAAA,MACf,GAAG;AAAA,KACL;AAEA,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,QAAA,CAAS,QAAQ,GAAA,EAAK;AAAA,MAChD,MAAM,IAAA,CAAK,SAAA,CAAU,EAAE,YAAA,EAAc,aAAa,CAAA;AAAA,MAClD,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,KAC/C,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,kBAAA,CAAmB,QAAA,CAAS,MAAA,EAAQ,gCAAgC,CAAA;AAAA,IAChF;AAEA,IAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAClC,IAAA,MAAM,OAAO,IAAA,CAAK,YAAA;AAClB,IAAA,OAAO,MAAM,OAAA,CAAQ,IAAA,EAAM,QAAQ,CAAA,GAAK,IAAA,CAAK,WAA4B,EAAC;AAAA,EAC5E;AACF","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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-chargepoint",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "description": "A Node.js/TypeScript wrapper for the ChargePoint EV charging network API. Based on python-chargepoint by Marc Billow.",
5
5
  "keywords": [
6
6
  "chargepoint",