@mxpicture/tesla-superchargers-cli 0.1.1
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.common.d.ts +3 -0
- package/dist/cli.common.d.ts.map +1 -0
- package/dist/cli.common.js +8 -0
- package/dist/cli.common.js.map +1 -0
- package/dist/cli.d.ts +28 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +116 -0
- package/dist/cli.js.map +1 -0
- package/dist/cli.option.d.ts +22 -0
- package/dist/cli.option.d.ts.map +1 -0
- package/dist/cli.option.js +31 -0
- package/dist/cli.option.js.map +1 -0
- package/dist/cli.parse.d.ts +12 -0
- package/dist/cli.parse.d.ts.map +1 -0
- package/dist/cli.parse.js +40 -0
- package/dist/cli.parse.js.map +1 -0
- package/dist/cli.run.d.ts +60 -0
- package/dist/cli.run.d.ts.map +1 -0
- package/dist/cli.run.js +179 -0
- package/dist/cli.run.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.common.d.ts","sourceRoot":"","sources":["../src/cli.common.ts"],"names":[],"mappings":"AAMA,2DAA2D;AAC3D,eAAO,MAAM,WAAW,QAAO,MAET,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
5
|
+
/** Reads the CLI package version from its package.json. */
|
|
6
|
+
export const readVersion = () => JSON.parse(readFileSync(resolve(__dirname, "../package.json"), "utf8"))
|
|
7
|
+
.version;
|
|
8
|
+
//# sourceMappingURL=cli.common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.common.js","sourceRoot":"","sources":["../src/cli.common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,2DAA2D;AAC3D,MAAM,CAAC,MAAM,WAAW,GAAG,GAAW,EAAE,CACtC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC,CAAC;KACpE,OAAiB,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* teslamate-superchargers
|
|
4
|
+
* =======================
|
|
5
|
+
* Maintain a Tesla Supercharger price history in a TeslaMate Postgres
|
|
6
|
+
* database (the `pic_*` tables, see `setup.sql`), fed from the public
|
|
7
|
+
* tesla.com endpoints via `@mxpicture/tesla-superchargers-api`.
|
|
8
|
+
*
|
|
9
|
+
* init-load wipe + refill pic_slugs from the live map feed
|
|
10
|
+
* init-load-file wipe + refill pic_slugs from a json dump
|
|
11
|
+
* sync-load snapshot-sync pic_slugs against the live map feed
|
|
12
|
+
* sync-load-file snapshot-sync pic_slugs against a json dump
|
|
13
|
+
* find-slugs list the slug rows near a coordinate
|
|
14
|
+
* find-charger resolve the charger at a coordinate (fetches on demand)
|
|
15
|
+
* find-prices the prices valid at a coordinate + timestamp
|
|
16
|
+
* find-unpriced-charges list TeslaMate charges without a cost
|
|
17
|
+
* process-unpriced-charges backfill costs from the stored price history
|
|
18
|
+
* find-failures list failing rows across the failure-tracked sources
|
|
19
|
+
* reset-failures clear failure state for a row or a whole source
|
|
20
|
+
* notify-failures Pushover-alert about not-yet-notified failures
|
|
21
|
+
* schedule daemon: daily pricing + notify (optional slug sync)
|
|
22
|
+
*
|
|
23
|
+
* The database connection comes from the standard `PG*` environment
|
|
24
|
+
* variables (`PGHOST`, `PGPORT`, `PGDATABASE`, `PGUSER`, `PGPASSWORD`).
|
|
25
|
+
* Alerts need `PUSHOVER_API_TOKEN` / `PUSHOVER_USER_KEY` (off when unset).
|
|
26
|
+
*/
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* teslamate-superchargers
|
|
4
|
+
* =======================
|
|
5
|
+
* Maintain a Tesla Supercharger price history in a TeslaMate Postgres
|
|
6
|
+
* database (the `pic_*` tables, see `setup.sql`), fed from the public
|
|
7
|
+
* tesla.com endpoints via `@mxpicture/tesla-superchargers-api`.
|
|
8
|
+
*
|
|
9
|
+
* init-load wipe + refill pic_slugs from the live map feed
|
|
10
|
+
* init-load-file wipe + refill pic_slugs from a json dump
|
|
11
|
+
* sync-load snapshot-sync pic_slugs against the live map feed
|
|
12
|
+
* sync-load-file snapshot-sync pic_slugs against a json dump
|
|
13
|
+
* find-slugs list the slug rows near a coordinate
|
|
14
|
+
* find-charger resolve the charger at a coordinate (fetches on demand)
|
|
15
|
+
* find-prices the prices valid at a coordinate + timestamp
|
|
16
|
+
* find-unpriced-charges list TeslaMate charges without a cost
|
|
17
|
+
* process-unpriced-charges backfill costs from the stored price history
|
|
18
|
+
* find-failures list failing rows across the failure-tracked sources
|
|
19
|
+
* reset-failures clear failure state for a row or a whole source
|
|
20
|
+
* notify-failures Pushover-alert about not-yet-notified failures
|
|
21
|
+
* schedule daemon: daily pricing + notify (optional slug sync)
|
|
22
|
+
*
|
|
23
|
+
* The database connection comes from the standard `PG*` environment
|
|
24
|
+
* variables (`PGHOST`, `PGPORT`, `PGDATABASE`, `PGUSER`, `PGPASSWORD`).
|
|
25
|
+
* Alerts need `PUSHOVER_API_TOKEN` / `PUSHOVER_USER_KEY` (off when unset).
|
|
26
|
+
*/
|
|
27
|
+
import { program } from "@commander-js/extra-typings";
|
|
28
|
+
import { argv, exit } from "node:process";
|
|
29
|
+
import { endSql } from "@mxpicture/tesla-superchargers-mate/store";
|
|
30
|
+
import { readVersion } from "./cli.common.js";
|
|
31
|
+
import { runInitLoad, runInitLoadByFile, runSyncLoad, runSyncLoadByFile, runFindSlugs, runFindCharger, runFindPrices, runFindUnpricedCharges, runProcessUnpricedCharges, runFindFailures, runResetFailures, runNotifyFailures, runSchedule, } from "./cli.run.js";
|
|
32
|
+
import { slugsJsonOption, latitudeOption, longitudeOption, timestampOption, sourceOption, thresholdOption, idOption, allOption, cronOption, syncCronOption, runOnStartOption, } from "./cli.option.js";
|
|
33
|
+
program
|
|
34
|
+
.name("teslamate-superchargers")
|
|
35
|
+
.version(readVersion())
|
|
36
|
+
.description("Fetch + store Tesla Supercharger locations and pricing");
|
|
37
|
+
program
|
|
38
|
+
.command("init-load")
|
|
39
|
+
.description("Delete slugs before fetching it again")
|
|
40
|
+
.action(runInitLoad);
|
|
41
|
+
program
|
|
42
|
+
.command("init-load-file")
|
|
43
|
+
.description("Delete slugs before loading file again")
|
|
44
|
+
.addOption(slugsJsonOption())
|
|
45
|
+
.action((o) => runInitLoadByFile(o));
|
|
46
|
+
program
|
|
47
|
+
.command("sync-load")
|
|
48
|
+
.description("Sync fetched slugs")
|
|
49
|
+
.action(runSyncLoad);
|
|
50
|
+
program
|
|
51
|
+
.command("sync-load-file")
|
|
52
|
+
.description("Sync loaded slugs from file")
|
|
53
|
+
.addOption(slugsJsonOption())
|
|
54
|
+
.action((o) => runSyncLoadByFile(o));
|
|
55
|
+
program
|
|
56
|
+
.command("find-slugs")
|
|
57
|
+
.description("Find slugs by coordinates")
|
|
58
|
+
.addOption(latitudeOption())
|
|
59
|
+
.addOption(longitudeOption())
|
|
60
|
+
.action((o) => runFindSlugs(o));
|
|
61
|
+
program
|
|
62
|
+
.command("find-charger")
|
|
63
|
+
.description("Find charger by coordinates")
|
|
64
|
+
.addOption(latitudeOption())
|
|
65
|
+
.addOption(longitudeOption())
|
|
66
|
+
.action((o) => runFindCharger(o));
|
|
67
|
+
program
|
|
68
|
+
.command("find-prices")
|
|
69
|
+
.description("Find charger by coordinates and date/time")
|
|
70
|
+
.addOption(latitudeOption())
|
|
71
|
+
.addOption(longitudeOption())
|
|
72
|
+
.addOption(timestampOption())
|
|
73
|
+
.action((o) => runFindPrices(o));
|
|
74
|
+
program
|
|
75
|
+
.command("find-unpriced-charges")
|
|
76
|
+
.description("Find unpriced charges")
|
|
77
|
+
.action(runFindUnpricedCharges);
|
|
78
|
+
program
|
|
79
|
+
.command("process-unpriced-charges")
|
|
80
|
+
.description("Process unpriced charges")
|
|
81
|
+
.action(runProcessUnpricedCharges);
|
|
82
|
+
program
|
|
83
|
+
.command("find-failures")
|
|
84
|
+
.description("List failing rows across the failure-tracked sources")
|
|
85
|
+
.addOption(sourceOption())
|
|
86
|
+
.addOption(thresholdOption())
|
|
87
|
+
.action((o) => runFindFailures(o));
|
|
88
|
+
program
|
|
89
|
+
.command("reset-failures")
|
|
90
|
+
.description("Reset failure state for a row (--id) or a whole source (--all)")
|
|
91
|
+
.addOption(sourceOption())
|
|
92
|
+
.addOption(idOption())
|
|
93
|
+
.addOption(allOption())
|
|
94
|
+
.action((o) => runResetFailures(o));
|
|
95
|
+
program
|
|
96
|
+
.command("notify-failures")
|
|
97
|
+
.description("Send a Pushover alert for not-yet-notified failures")
|
|
98
|
+
.addOption(thresholdOption())
|
|
99
|
+
.action((o) => runNotifyFailures(o));
|
|
100
|
+
program
|
|
101
|
+
.command("schedule")
|
|
102
|
+
.description("Run the daily pricing + notify daemon (optional slug sync)")
|
|
103
|
+
.addOption(cronOption())
|
|
104
|
+
.addOption(syncCronOption())
|
|
105
|
+
.addOption(runOnStartOption())
|
|
106
|
+
.action((o) => runSchedule(o));
|
|
107
|
+
program
|
|
108
|
+
.parseAsync(argv)
|
|
109
|
+
// close the shared postgres pool (if one was opened) so the process exits
|
|
110
|
+
// instead of waiting out the idle_timeout
|
|
111
|
+
.then(() => endSql())
|
|
112
|
+
.catch((e) => {
|
|
113
|
+
console.error(e);
|
|
114
|
+
exit(1);
|
|
115
|
+
});
|
|
116
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Option } from "@commander-js/extra-typings";
|
|
2
|
+
/** Commander option: path to a slugs json dump (as served by get-locations). */
|
|
3
|
+
export declare const slugsJsonOption: () => Option<"-s, --slugs [slugs]", undefined, undefined, string, true, undefined>;
|
|
4
|
+
export declare const latitudeOption: () => Option<"--lat <latitude>", undefined, undefined, undefined, true, undefined>;
|
|
5
|
+
export declare const longitudeOption: () => Option<"--lon <longitude>", undefined, undefined, undefined, true, undefined>;
|
|
6
|
+
/** Commander option: ISO 8601 timestamp to price at (default: now). */
|
|
7
|
+
export declare const timestampOption: () => Option<"--at <timestamp>", undefined, undefined, Date, false, undefined>;
|
|
8
|
+
/** Which failure-tracked source(s) to act on (default: all). */
|
|
9
|
+
export declare const sourceOption: () => Option<"--source <source>", undefined, "all", undefined, false, "charges" | "chargers" | "slugs" | "all">;
|
|
10
|
+
/** Minimum failure_count to include (default: the deprioritize threshold). */
|
|
11
|
+
export declare const thresholdOption: () => Option<"--threshold <count>", undefined, 3, number, false, undefined>;
|
|
12
|
+
/** Row id to reset (charges: the charging_processes_id). */
|
|
13
|
+
export declare const idOption: () => Option<"--id <id>", undefined, undefined, undefined, false, undefined>;
|
|
14
|
+
/** Reset every failing row of the source instead of a single id. */
|
|
15
|
+
export declare const allOption: () => Option<"--all", undefined, undefined, undefined, false, undefined>;
|
|
16
|
+
/** Cron expression for the pricing + notify tick (default: daily at 03:00). */
|
|
17
|
+
export declare const cronOption: () => Option<"--cron <expression>", undefined, "0 3 * * *", undefined, false, undefined>;
|
|
18
|
+
/** Cron expression for an optional slug sync job (disabled unless set). */
|
|
19
|
+
export declare const syncCronOption: () => Option<"--sync-cron <expression>", undefined, undefined, undefined, false, undefined>;
|
|
20
|
+
/** Run one tick immediately on startup, before waiting for the first cron fire. */
|
|
21
|
+
export declare const runOnStartOption: () => Option<"--run-on-start", undefined, undefined, undefined, false, undefined>;
|
|
22
|
+
//# sourceMappingURL=cli.option.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.option.d.ts","sourceRoot":"","sources":["../src/cli.option.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAMrD,gFAAgF;AAChF,eAAO,MAAM,eAAe,oFAGH,CAAC;AAE1B,eAAO,MAAM,cAAc,oFACuC,CAAC;AAEnE,eAAO,MAAM,eAAe,qFACwC,CAAC;AAErE,uEAAuE;AACvE,eAAO,MAAM,eAAe,gFAIC,CAAC;AAE9B,gEAAgE;AAChE,eAAO,MAAM,YAAY,iHAGG,CAAC;AAE7B,8EAA8E;AAC9E,eAAO,MAAM,eAAe,6EAGgB,CAAC;AAE7C,4DAA4D;AAC5D,eAAO,MAAM,QAAQ,8EAAmD,CAAC;AAEzE,oEAAoE;AACpE,eAAO,MAAM,SAAS,0EACuC,CAAC;AAE9D,+EAA+E;AAC/E,eAAO,MAAM,UAAU,0FAIC,CAAC;AAEzB,2EAA2E;AAC3E,eAAO,MAAM,cAAc,6FAIxB,CAAC;AAEJ,mFAAmF;AACnF,eAAO,MAAM,gBAAgB,mFACwC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Option } from "@commander-js/extra-typings";
|
|
2
|
+
import { FAILURE_DEPRIORITIZE_THRESHOLD } from "@mxpicture/tesla-superchargers-api/common";
|
|
3
|
+
import { parseIntArg, parsePath, parseTimestamp } from "./cli.parse.js";
|
|
4
|
+
// ---------- commander options ----------
|
|
5
|
+
/** Commander option: path to a slugs json dump (as served by get-locations). */
|
|
6
|
+
export const slugsJsonOption = () => new Option("-s, --slugs [slugs]", "Path to slugs json file")
|
|
7
|
+
.makeOptionMandatory()
|
|
8
|
+
.argParser(parsePath);
|
|
9
|
+
export const latitudeOption = () => new Option("--lat <latitude>", "latitude").makeOptionMandatory();
|
|
10
|
+
export const longitudeOption = () => new Option("--lon <longitude>", "longitude").makeOptionMandatory();
|
|
11
|
+
/** Commander option: ISO 8601 timestamp to price at (default: now). */
|
|
12
|
+
export const timestampOption = () => new Option("--at <timestamp>", "ISO 8601 timestamp to find prices at (default: now)").argParser(parseTimestamp);
|
|
13
|
+
/** Which failure-tracked source(s) to act on (default: all). */
|
|
14
|
+
export const sourceOption = () => new Option("--source <source>", "Failure source")
|
|
15
|
+
.choices(["charges", "chargers", "slugs", "all"])
|
|
16
|
+
.default("all");
|
|
17
|
+
/** Minimum failure_count to include (default: the deprioritize threshold). */
|
|
18
|
+
export const thresholdOption = () => new Option("--threshold <count>", "Minimum failure count")
|
|
19
|
+
.argParser(parseIntArg)
|
|
20
|
+
.default(FAILURE_DEPRIORITIZE_THRESHOLD);
|
|
21
|
+
/** Row id to reset (charges: the charging_processes_id). */
|
|
22
|
+
export const idOption = () => new Option("--id <id>", "Row id to reset");
|
|
23
|
+
/** Reset every failing row of the source instead of a single id. */
|
|
24
|
+
export const allOption = () => new Option("--all", "Reset all failing rows of the source");
|
|
25
|
+
/** Cron expression for the pricing + notify tick (default: daily at 03:00). */
|
|
26
|
+
export const cronOption = () => new Option("--cron <expression>", "Cron expression for the pricing + notify tick").default("0 3 * * *");
|
|
27
|
+
/** Cron expression for an optional slug sync job (disabled unless set). */
|
|
28
|
+
export const syncCronOption = () => new Option("--sync-cron <expression>", "Cron expression for the slug sync (disabled unless set)");
|
|
29
|
+
/** Run one tick immediately on startup, before waiting for the first cron fire. */
|
|
30
|
+
export const runOnStartOption = () => new Option("--run-on-start", "Run one tick immediately on startup");
|
|
31
|
+
//# sourceMappingURL=cli.option.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.option.js","sourceRoot":"","sources":["../src/cli.option.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AACrD,OAAO,EAAE,8BAA8B,EAAE,MAAM,2CAA2C,CAAC;AAC3F,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAExE,0CAA0C;AAE1C,gFAAgF;AAChF,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,EAAE,CAClC,IAAI,MAAM,CAAC,qBAAqB,EAAE,yBAAyB,CAAC;KACzD,mBAAmB,EAAE;KACrB,SAAS,CAAC,SAAS,CAAC,CAAC;AAE1B,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE,CACjC,IAAI,MAAM,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAAC,mBAAmB,EAAE,CAAC;AAEnE,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,EAAE,CAClC,IAAI,MAAM,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAC,mBAAmB,EAAE,CAAC;AAErE,uEAAuE;AACvE,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,EAAE,CAClC,IAAI,MAAM,CACR,kBAAkB,EAClB,qDAAqD,CACtD,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;AAE9B,gEAAgE;AAChE,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,EAAE,CAC/B,IAAI,MAAM,CAAC,mBAAmB,EAAE,gBAAgB,CAAC;KAC9C,OAAO,CAAC,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,CAAU,CAAC;KACzD,OAAO,CAAC,KAAc,CAAC,CAAC;AAE7B,8EAA8E;AAC9E,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,EAAE,CAClC,IAAI,MAAM,CAAC,qBAAqB,EAAE,uBAAuB,CAAC;KACvD,SAAS,CAAC,WAAW,CAAC;KACtB,OAAO,CAAC,8BAA8B,CAAC,CAAC;AAE7C,4DAA4D;AAC5D,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAI,MAAM,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;AAEzE,oEAAoE;AACpE,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE,CAC5B,IAAI,MAAM,CAAC,OAAO,EAAE,sCAAsC,CAAC,CAAC;AAE9D,+EAA+E;AAC/E,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,EAAE,CAC7B,IAAI,MAAM,CACR,qBAAqB,EACrB,+CAA+C,CAChD,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;AAEzB,2EAA2E;AAC3E,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE,CACjC,IAAI,MAAM,CACR,0BAA0B,EAC1B,yDAAyD,CAC1D,CAAC;AAEJ,mFAAmF;AACnF,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,EAAE,CACnC,IAAI,MAAM,CAAC,gBAAgB,EAAE,qCAAqC,CAAC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Parses a non-negative float (e.g. --delay, --radius). */
|
|
2
|
+
export declare const parseFloatArg: (v: string) => number;
|
|
3
|
+
/** Parses a non-negative integer (e.g. --limit). */
|
|
4
|
+
export declare const parseIntArg: (v: string) => number;
|
|
5
|
+
/** Parses a positive integer number of days (e.g. --*-every, --outdated-age). */
|
|
6
|
+
export declare const parseDaysArg: (v: string) => number;
|
|
7
|
+
/** Validates an HH:MM (24h) time string (e.g. --at). */
|
|
8
|
+
export declare const parseTime: (v: string) => string;
|
|
9
|
+
/** Parses an ISO 8601 timestamp (e.g. --at on find-prices). */
|
|
10
|
+
export declare const parseTimestamp: (v: string) => Date;
|
|
11
|
+
export declare const parsePath: (path: string) => string;
|
|
12
|
+
//# sourceMappingURL=cli.parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.parse.d.ts","sourceRoot":"","sources":["../src/cli.parse.ts"],"names":[],"mappings":"AAMA,4DAA4D;AAC5D,eAAO,MAAM,aAAa,GAAI,GAAG,MAAM,KAAG,MAKzC,CAAC;AAEF,oDAAoD;AACpD,eAAO,MAAM,WAAW,GAAI,GAAG,MAAM,KAAG,MAKvC,CAAC;AAEF,iFAAiF;AACjF,eAAO,MAAM,YAAY,GAAI,GAAG,MAAM,KAAG,MAKxC,CAAC;AAEF,wDAAwD;AACxD,eAAO,MAAM,SAAS,GAAI,GAAG,MAAM,KAAG,MAIrC,CAAC;AAEF,+DAA+D;AAC/D,eAAO,MAAM,cAAc,GAAI,GAAG,MAAM,KAAG,IAK1C,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,KAAG,MACO,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { InvalidArgumentError } from "@commander-js/extra-typings";
|
|
2
|
+
import { isAbsolute, resolve } from "node:path";
|
|
3
|
+
import { cwd } from "node:process";
|
|
4
|
+
// ---------- argument parsers ----------
|
|
5
|
+
/** Parses a non-negative float (e.g. --delay, --radius). */
|
|
6
|
+
export const parseFloatArg = (v) => {
|
|
7
|
+
const n = Number(v);
|
|
8
|
+
if (!Number.isFinite(n) || n < 0)
|
|
9
|
+
throw new InvalidArgumentError("must be a non-negative number");
|
|
10
|
+
return n;
|
|
11
|
+
};
|
|
12
|
+
/** Parses a non-negative integer (e.g. --limit). */
|
|
13
|
+
export const parseIntArg = (v) => {
|
|
14
|
+
const n = parseInt(v, 10);
|
|
15
|
+
if (isNaN(n) || n < 0)
|
|
16
|
+
throw new InvalidArgumentError("must be a non-negative integer");
|
|
17
|
+
return n;
|
|
18
|
+
};
|
|
19
|
+
/** Parses a positive integer number of days (e.g. --*-every, --outdated-age). */
|
|
20
|
+
export const parseDaysArg = (v) => {
|
|
21
|
+
const n = parseInt(v, 10);
|
|
22
|
+
if (!Number.isInteger(n) || n < 1)
|
|
23
|
+
throw new InvalidArgumentError("must be a positive integer (>= 1)");
|
|
24
|
+
return n;
|
|
25
|
+
};
|
|
26
|
+
/** Validates an HH:MM (24h) time string (e.g. --at). */
|
|
27
|
+
export const parseTime = (v) => {
|
|
28
|
+
if (!/^([01]\d|2[0-3]):[0-5]\d$/.test(v))
|
|
29
|
+
throw new InvalidArgumentError("expected HH:MM (24h)");
|
|
30
|
+
return v;
|
|
31
|
+
};
|
|
32
|
+
/** Parses an ISO 8601 timestamp (e.g. --at on find-prices). */
|
|
33
|
+
export const parseTimestamp = (v) => {
|
|
34
|
+
const d = new Date(v);
|
|
35
|
+
if (isNaN(d.getTime()))
|
|
36
|
+
throw new InvalidArgumentError("expected an ISO 8601 timestamp");
|
|
37
|
+
return d;
|
|
38
|
+
};
|
|
39
|
+
export const parsePath = (path) => isAbsolute(path) ? path : resolve(cwd(), path);
|
|
40
|
+
//# sourceMappingURL=cli.parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.parse.js","sourceRoot":"","sources":["../src/cli.parse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAEnC,yCAAyC;AAEzC,4DAA4D;AAC5D,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAS,EAAU,EAAE;IACjD,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACpB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAC9B,MAAM,IAAI,oBAAoB,CAAC,+BAA+B,CAAC,CAAC;IAClE,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF,oDAAoD;AACpD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAS,EAAU,EAAE;IAC/C,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1B,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QACnB,MAAM,IAAI,oBAAoB,CAAC,gCAAgC,CAAC,CAAC;IACnE,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF,iFAAiF;AACjF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAS,EAAU,EAAE;IAChD,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAC/B,MAAM,IAAI,oBAAoB,CAAC,mCAAmC,CAAC,CAAC;IACtE,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF,wDAAwD;AACxD,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAS,EAAU,EAAE;IAC7C,IAAI,CAAC,2BAA2B,CAAC,IAAI,CAAC,CAAC,CAAC;QACtC,MAAM,IAAI,oBAAoB,CAAC,sBAAsB,CAAC,CAAC;IACzD,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF,+DAA+D;AAC/D,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAS,EAAQ,EAAE;IAChD,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IACtB,IAAI,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,oBAAoB,CAAC,gCAAgC,CAAC,CAAC;IACnE,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAY,EAAU,EAAE,CAChD,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
type FailureSourceArg = "charges" | "chargers" | "slugs" | "all";
|
|
2
|
+
export declare const runInitLoad: () => Promise<void>;
|
|
3
|
+
export declare const runInitLoadByFile: (o: {
|
|
4
|
+
slugs: string | true;
|
|
5
|
+
}) => Promise<void>;
|
|
6
|
+
export declare const runSyncLoad: () => Promise<void>;
|
|
7
|
+
export declare const runSyncLoadByFile: (o: {
|
|
8
|
+
slugs: string | true;
|
|
9
|
+
}) => Promise<void>;
|
|
10
|
+
export declare const runFindSlugs: (o: {
|
|
11
|
+
lat: string;
|
|
12
|
+
lon: string;
|
|
13
|
+
}) => Promise<void>;
|
|
14
|
+
export declare const runFindCharger: (o: {
|
|
15
|
+
lat: string;
|
|
16
|
+
lon: string;
|
|
17
|
+
}) => Promise<void>;
|
|
18
|
+
export declare const runFindPrices: (o: {
|
|
19
|
+
lat: string;
|
|
20
|
+
lon: string;
|
|
21
|
+
at?: Date;
|
|
22
|
+
}) => Promise<void>;
|
|
23
|
+
export declare const runFindUnpricedCharges: () => Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Backfill `cost` on unpriced charges: for each charge the Supercharger
|
|
26
|
+
* prices valid at the charge's start are looked up by coordinate, and the
|
|
27
|
+
* Tesla per-kWh charging rate × the charge's energy (metered
|
|
28
|
+
* `charge_energy_used`, falling back to `charge_energy_added`) is written
|
|
29
|
+
* back. Charges not at a known Supercharger, without a kWh-based Tesla
|
|
30
|
+
* charging rate, or without a usable energy value are skipped and stay
|
|
31
|
+
* unpriced. Time-of-use is resolved at the charge's start instant; a charge
|
|
32
|
+
* spanning into the next window keeps the starting rate.
|
|
33
|
+
*/
|
|
34
|
+
export declare const runProcessUnpricedCharges: () => Promise<void>;
|
|
35
|
+
export declare const runFindFailures: (o: {
|
|
36
|
+
source: FailureSourceArg;
|
|
37
|
+
threshold: number;
|
|
38
|
+
}) => Promise<void>;
|
|
39
|
+
export declare const runResetFailures: (o: {
|
|
40
|
+
source: FailureSourceArg;
|
|
41
|
+
id?: string;
|
|
42
|
+
all?: boolean;
|
|
43
|
+
}) => Promise<void>;
|
|
44
|
+
export declare const runNotifyFailures: (o: {
|
|
45
|
+
threshold: number;
|
|
46
|
+
}) => Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Long-running daemon: a croner job runs the pricing backfill + failure
|
|
49
|
+
* notification on `--cron` (daily at 03:00 by default), and — only when
|
|
50
|
+
* `--sync-cron` is given — a second job runs the slug sync. A tick that throws
|
|
51
|
+
* is logged and paged but never stops the daemon. Never resolves; the shared
|
|
52
|
+
* pool stays open until SIGINT/SIGTERM closes it and exits.
|
|
53
|
+
*/
|
|
54
|
+
export declare const runSchedule: (o: {
|
|
55
|
+
cron: string;
|
|
56
|
+
syncCron?: string;
|
|
57
|
+
runOnStart?: boolean;
|
|
58
|
+
}) => Promise<never>;
|
|
59
|
+
export {};
|
|
60
|
+
//# sourceMappingURL=cli.run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.run.d.ts","sourceRoot":"","sources":["../src/cli.run.ts"],"names":[],"mappings":"AAkBA,KAAK,gBAAgB,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,KAAK,CAAC;AAEjE,eAAO,MAAM,WAAW,QAAa,OAAO,CAAC,IAAI,CAIhD,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAU,GAAG;IACzC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,KAAG,OAAO,CAAC,IAAI,CAQf,CAAC;AAEF,eAAO,MAAM,WAAW,QAAa,OAAO,CAAC,IAAI,CAIhD,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAU,GAAG;IACzC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,KAAG,OAAO,CAAC,IAAI,CAQf,CAAC;AAEF,eAAO,MAAM,YAAY,GAAU,GAAG;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb,KAAG,OAAO,CAAC,IAAI,CAWf,CAAC;AAEF,eAAO,MAAM,cAAc,GAAU,GAAG;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb,KAAG,OAAO,CAAC,IAAI,CAaf,CAAC;AAEF,eAAO,MAAM,aAAa,GAAU,GAAG;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,CAAC,EAAE,IAAI,CAAC;CACX,KAAG,OAAO,CAAC,IAAI,CAcf,CAAC;AAEF,eAAO,MAAM,sBAAsB,QAAa,OAAO,CAAC,IAAI,CAI3D,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,yBAAyB,QAAa,OAAO,CAAC,IAAI,CA+B9D,CAAC;AAEF,eAAO,MAAM,eAAe,GAAU,GAAG;IACvC,MAAM,EAAE,gBAAgB,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB,KAAG,OAAO,CAAC,IAAI,CAef,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAU,GAAG;IACxC,MAAM,EAAE,gBAAgB,CAAC;IACzB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,KAAG,OAAO,CAAC,IAAI,CAkBf,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAU,GAAG;IACzC,SAAS,EAAE,MAAM,CAAC;CACnB,KAAG,OAAO,CAAC,IAAI,CAOf,CAAC;AAuBF;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GAAU,GAAG;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,KAAG,OAAO,CAAC,KAAK,CA4BhB,CAAC"}
|
package/dist/cli.run.js
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { slugsApi, chargersApi, chargingProcessesApi, failuresApi, } from "@mxpicture/tesla-superchargers-api/api";
|
|
2
|
+
import { pushoverConfigFromEnv, sendPushover, } from "@mxpicture/tesla-superchargers-api/common";
|
|
3
|
+
import { endSql } from "@mxpicture/tesla-superchargers-mate/store";
|
|
4
|
+
import { Cron } from "croner";
|
|
5
|
+
import { dirname, resolve } from "node:path";
|
|
6
|
+
import { exit } from "node:process";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
export const runInitLoad = async () => {
|
|
10
|
+
console.log("----- init load slugs ------------------");
|
|
11
|
+
const summary = await slugsApi().initialLoad();
|
|
12
|
+
console.log(summary);
|
|
13
|
+
};
|
|
14
|
+
export const runInitLoadByFile = async (o) => {
|
|
15
|
+
console.log("----- init load slugs by file ------------------");
|
|
16
|
+
const summary = await slugsApi().initialLoadFile(o.slugs !== true
|
|
17
|
+
? o.slugs
|
|
18
|
+
: resolve(__dirname, "../../../compare/data/slugs.json"));
|
|
19
|
+
console.log(summary);
|
|
20
|
+
};
|
|
21
|
+
export const runSyncLoad = async () => {
|
|
22
|
+
console.log("----- sync slugs ------------------");
|
|
23
|
+
const summary = await slugsApi().syncLoad();
|
|
24
|
+
console.log(summary);
|
|
25
|
+
};
|
|
26
|
+
export const runSyncLoadByFile = async (o) => {
|
|
27
|
+
console.log("----- sync slugs by file ------------------");
|
|
28
|
+
const summary = await slugsApi().syncLoadFile(o.slugs !== true
|
|
29
|
+
? o.slugs
|
|
30
|
+
: resolve(__dirname, "../../../compare/data/slugs.json"));
|
|
31
|
+
console.log(summary);
|
|
32
|
+
};
|
|
33
|
+
export const runFindSlugs = async (o) => {
|
|
34
|
+
const slugs = await slugsApi().find({
|
|
35
|
+
latitude: o.lat,
|
|
36
|
+
longitude: o.lon,
|
|
37
|
+
});
|
|
38
|
+
console.log(`${slugs.length} slugs (tesla_uuid) found:`);
|
|
39
|
+
for (const slug of slugs)
|
|
40
|
+
console.log(`- ${slug.location_url_slug} (${slug.tesla_uuid}): ${Math.round(slug.distance_km * 1000)} m`);
|
|
41
|
+
};
|
|
42
|
+
export const runFindCharger = async (o) => {
|
|
43
|
+
const charger = await chargersApi().find({
|
|
44
|
+
latitude: o.lat,
|
|
45
|
+
longitude: o.lon,
|
|
46
|
+
});
|
|
47
|
+
if (!charger) {
|
|
48
|
+
console.log(`no charger found for ${o.lat} ${o.lon}`);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
console.log(`charger found:`);
|
|
52
|
+
console.log(charger);
|
|
53
|
+
};
|
|
54
|
+
export const runFindPrices = async (o) => {
|
|
55
|
+
const at = o.at ?? new Date();
|
|
56
|
+
const pricebooks = await chargersApi().findPrices({ latitude: o.lat, longitude: o.lon }, at);
|
|
57
|
+
if (!pricebooks.length) {
|
|
58
|
+
console.log(`no prices found for ${o.lat} ${o.lon} at ${at.toISOString()}`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
console.log(`prices found:`);
|
|
62
|
+
console.log(pricebooks);
|
|
63
|
+
};
|
|
64
|
+
export const runFindUnpricedCharges = async () => {
|
|
65
|
+
const charges = await chargingProcessesApi().getUnpricedCharges();
|
|
66
|
+
console.log(`${charges.length} charges found:`);
|
|
67
|
+
console.log(charges);
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Backfill `cost` on unpriced charges: for each charge the Supercharger
|
|
71
|
+
* prices valid at the charge's start are looked up by coordinate, and the
|
|
72
|
+
* Tesla per-kWh charging rate × the charge's energy (metered
|
|
73
|
+
* `charge_energy_used`, falling back to `charge_energy_added`) is written
|
|
74
|
+
* back. Charges not at a known Supercharger, without a kWh-based Tesla
|
|
75
|
+
* charging rate, or without a usable energy value are skipped and stay
|
|
76
|
+
* unpriced. Time-of-use is resolved at the charge's start instant; a charge
|
|
77
|
+
* spanning into the next window keeps the starting rate.
|
|
78
|
+
*/
|
|
79
|
+
export const runProcessUnpricedCharges = async () => {
|
|
80
|
+
const summary = await chargingProcessesApi().runPricing();
|
|
81
|
+
console.log(`${summary.unpricedCharges} unpriced charges found`);
|
|
82
|
+
let priced = 0;
|
|
83
|
+
for (const { charge, topic, energy, rate, cost } of summary.items) {
|
|
84
|
+
switch (topic) {
|
|
85
|
+
case "noRate":
|
|
86
|
+
console.warn(`- charge ${charge.id}: no rate found, skipped`);
|
|
87
|
+
break;
|
|
88
|
+
case "noEnergyValue":
|
|
89
|
+
console.warn(`- charge ${charge.id}: rate found but no usable energy value, skipped`);
|
|
90
|
+
break;
|
|
91
|
+
case "chargeUpdated":
|
|
92
|
+
priced++;
|
|
93
|
+
console.log(`- charge ${charge.id} (${charge.start_date.toISOString()}): ` +
|
|
94
|
+
`${energy} kWh × ${rate?.rate} = ${cost} ${rate?.currencyCode}`);
|
|
95
|
+
break;
|
|
96
|
+
default:
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
console.log(`${priced} of ${summary.unpricedCharges} charges priced`);
|
|
101
|
+
};
|
|
102
|
+
export const runFindFailures = async (o) => {
|
|
103
|
+
const failed = await failuresApi().getFailed(o.source, o.threshold);
|
|
104
|
+
console.log(`failures (>= ${o.threshold}): ${failed.charges.length} charges, ` +
|
|
105
|
+
`${failed.chargers.length} chargers, ${failed.slugs.length} slugs`);
|
|
106
|
+
for (const c of failed.charges)
|
|
107
|
+
console.log(`- charge #${c.charging_processes_id} ` +
|
|
108
|
+
`(${c.start_date ? c.start_date.toISOString() : "?"}): ${c.failure_count} failures`);
|
|
109
|
+
for (const c of failed.chargers)
|
|
110
|
+
console.log(`- charger ${c.name}, ${c.city}: ${c.failure_count} failures`);
|
|
111
|
+
for (const s of failed.slugs)
|
|
112
|
+
console.log(`- slug ${s.location_url_slug}: ${s.failure_count} failures`);
|
|
113
|
+
};
|
|
114
|
+
export const runResetFailures = async (o) => {
|
|
115
|
+
if (Boolean(o.id) === Boolean(o.all))
|
|
116
|
+
throw new Error("provide exactly one of --id or --all");
|
|
117
|
+
if (o.id !== undefined) {
|
|
118
|
+
if (o.source === "all")
|
|
119
|
+
throw new Error("--id requires a concrete --source (charges, chargers or slugs)");
|
|
120
|
+
await failuresApi().resetFailed(o.source, o.id);
|
|
121
|
+
console.log(`reset ${o.source} failure for id ${o.id}`);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const counts = await failuresApi().resetAllFailed(o.source);
|
|
125
|
+
console.log(`reset ${counts.charges} charges, ${counts.chargers} chargers, ${counts.slugs} slugs`);
|
|
126
|
+
};
|
|
127
|
+
export const runNotifyFailures = async (o) => {
|
|
128
|
+
const summary = await failuresApi().notifyFailures(o.threshold, console.log);
|
|
129
|
+
console.log(summary);
|
|
130
|
+
if (!summary.configured)
|
|
131
|
+
console.log("pushover not configured: set PUSHOVER_API_TOKEN and PUSHOVER_USER_KEY to enable alerts");
|
|
132
|
+
};
|
|
133
|
+
/** Build a tick that logs its failure and pages it (Decision 8), never throwing. */
|
|
134
|
+
const guardedTick = (title, run) => async () => {
|
|
135
|
+
try {
|
|
136
|
+
await run();
|
|
137
|
+
}
|
|
138
|
+
catch (e) {
|
|
139
|
+
console.error(e);
|
|
140
|
+
const cfg = pushoverConfigFromEnv();
|
|
141
|
+
if (cfg)
|
|
142
|
+
await sendPushover(cfg, {
|
|
143
|
+
title,
|
|
144
|
+
message: e instanceof Error ? e.message : String(e),
|
|
145
|
+
priority: 1,
|
|
146
|
+
}, console.log);
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* Long-running daemon: a croner job runs the pricing backfill + failure
|
|
151
|
+
* notification on `--cron` (daily at 03:00 by default), and — only when
|
|
152
|
+
* `--sync-cron` is given — a second job runs the slug sync. A tick that throws
|
|
153
|
+
* is logged and paged but never stops the daemon. Never resolves; the shared
|
|
154
|
+
* pool stays open until SIGINT/SIGTERM closes it and exits.
|
|
155
|
+
*/
|
|
156
|
+
export const runSchedule = async (o) => {
|
|
157
|
+
const tick = guardedTick("❌ Supercharger scheduler run failed", async () => {
|
|
158
|
+
await runProcessUnpricedCharges();
|
|
159
|
+
console.log(await failuresApi().notifyFailures(undefined, console.log));
|
|
160
|
+
});
|
|
161
|
+
const jobs = [new Cron(o.cron, { protect: true }, tick)];
|
|
162
|
+
if (o.syncCron)
|
|
163
|
+
jobs.push(new Cron(o.syncCron, { protect: true }, guardedTick("❌ Supercharger slug sync failed", async () => {
|
|
164
|
+
console.log(await slugsApi().syncLoad());
|
|
165
|
+
})));
|
|
166
|
+
const shutdown = () => {
|
|
167
|
+
for (const j of jobs)
|
|
168
|
+
j.stop();
|
|
169
|
+
void endSql().finally(() => exit(0));
|
|
170
|
+
};
|
|
171
|
+
process.on("SIGINT", shutdown);
|
|
172
|
+
process.on("SIGTERM", shutdown);
|
|
173
|
+
for (const j of jobs)
|
|
174
|
+
console.log(`next run: ${j.nextRun()?.toISOString()}`);
|
|
175
|
+
if (o.runOnStart)
|
|
176
|
+
await tick();
|
|
177
|
+
return await new Promise(() => { });
|
|
178
|
+
};
|
|
179
|
+
//# sourceMappingURL=cli.run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.run.js","sourceRoot":"","sources":["../src/cli.run.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mxpicture/tesla-superchargers-cli",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "CLI to fetch + store Tesla Supercharger locations and pricing",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"author": "MXPicture",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/MXPicture/npm-tesla-superchargers.git"
|
|
11
|
+
},
|
|
12
|
+
"bin": {
|
|
13
|
+
"teslamate-superchargers": "./dist/cli.js"
|
|
14
|
+
},
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./src/index.ts",
|
|
18
|
+
"default": "./dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./package.json": "./package.json"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=24"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"lint": "eslint \"src/**/*.ts\" --ext .ts --cache --cache-strategy content",
|
|
30
|
+
"lint:ci": "eslint \"src/**/*.ts\" --ext .ts --max-warnings=0",
|
|
31
|
+
"build": "tsc -b .",
|
|
32
|
+
"test": "tsc -b . && vitest run --passWithNoTests"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@commander-js/extra-typings": "^14.0.0",
|
|
39
|
+
"@mxpicture/tesla-superchargers-api": "workspace:*",
|
|
40
|
+
"@mxpicture/tesla-superchargers-mate": "workspace:*",
|
|
41
|
+
"commander": "^14.0.3",
|
|
42
|
+
"croner": "^10.0.1"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "^25.2.3",
|
|
46
|
+
"eslint": "^9.39.3",
|
|
47
|
+
"typescript": "^5.9.3",
|
|
48
|
+
"vitest": "^4.0.18"
|
|
49
|
+
}
|
|
50
|
+
}
|