@mxpicture/teslamate-extended-cli 2.1.51

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.
@@ -0,0 +1,64 @@
1
+ import { Option } from "@commander-js/extra-typings";
2
+ import { type FetchOptions, type FetchScope } from "@mxpicture/teslamate-extended-api/api";
3
+ import { type SuperchargerStore } from "@mxpicture/teslamate-extended-api/store";
4
+ /** Reads the CLI package version from its package.json. */
5
+ export declare const readVersion: () => string;
6
+ /** One day in milliseconds — the schedule interval. */
7
+ export declare const DAY_MS: number;
8
+ /** Parses a non-negative float (e.g. --delay). */
9
+ export declare const parseFloatArg: (v: string) => number;
10
+ /** Parses a non-negative integer (e.g. --limit). */
11
+ export declare const parseIntArg: (v: string) => number;
12
+ /** Validates an HH:MM (24h) time string (e.g. --at). */
13
+ export declare const parseTime: (v: string) => string;
14
+ /** Commander option: restrict to a single country. */
15
+ export declare const countryOption: Option<"-c, --country <name>", undefined, undefined, undefined, false, undefined>;
16
+ /** Commander option: restrict to a single region. */
17
+ export declare const regionOption: Option<"-R, --region <name>", undefined, undefined, undefined, false, undefined>;
18
+ /** Commander option: all Superchargers worldwide. */
19
+ export declare const allOption: Option<"-a, --all", undefined, undefined, undefined, false, undefined>;
20
+ /** Commander option: pricing locale. */
21
+ export declare const localeOption: Option<"-l, --locale <locale>", undefined, "en-US", undefined, false, undefined>;
22
+ /** Commander option: politeness delay between requests (seconds). */
23
+ export declare const delayOption: Option<"-d, --delay <seconds>", undefined, 0.35, number, false, undefined>;
24
+ /** Commander option: cap the number of sites fetched (0 = no cap). */
25
+ export declare const limitOption: Option<"-n, --limit <count>", undefined, 0, number, false, undefined>;
26
+ /** Commander option: JSON snapshot output directory. */
27
+ export declare const outOption: Option<"-o, --out <dir>", undefined, undefined, undefined, false, undefined>;
28
+ /** Commander option: Postgres connection URL. */
29
+ export declare const postgresUrlOption: Option<"-p, --postgres-url <url>", undefined, undefined, undefined, false, undefined>;
30
+ /** Commander option: Postgres table name. */
31
+ export declare const pgTableOption: Option<"--pg-table <name>", undefined, "supercharger_price_history", undefined, false, undefined>;
32
+ /** Commander option: daily run time for `schedule` (24h, local). */
33
+ export declare const atOption: Option<"-t, --at <HH:MM>", undefined, "03:30", string, false, undefined>;
34
+ /** Options common to `fetch` and `schedule`. */
35
+ export interface CommonOpts {
36
+ country?: string;
37
+ region?: string;
38
+ all?: boolean;
39
+ locale: string;
40
+ delay: number;
41
+ limit: number;
42
+ out?: string;
43
+ postgresUrl?: string;
44
+ pgTable: string;
45
+ }
46
+ /** `schedule` options: the common ones plus the daily run time. */
47
+ export type ScheduleOpts = CommonOpts & {
48
+ at: string;
49
+ };
50
+ /** Resolves the single scope flag (exactly one of country/region/all). */
51
+ export declare function toScope(o: CommonOpts): FetchScope;
52
+ /** Maps CLI options to the api fetch options. */
53
+ export declare function toFetchOptions(o: CommonOpts): FetchOptions;
54
+ /** Builds the sinks the user asked for (CLI flag or env). At least one required. */
55
+ export declare function buildStores(o: CommonOpts): SuperchargerStore[];
56
+ /** Fetches one snapshot, stores it, and closes the sinks. */
57
+ export declare function runOnce(o: CommonOpts): Promise<void>;
58
+ /** ms from now until the next HH:MM (local); rolls to tomorrow if already passed. */
59
+ export declare function msUntil(at: string): number;
60
+ /** Runs once on start, then every day at o.at — keeping the process alive. */
61
+ export declare function scheduleDaily(o: ScheduleOpts): Promise<void>;
62
+ /** Prints the countries and regions that have Superchargers. */
63
+ export declare function listCountries(): Promise<void>;
64
+ //# sourceMappingURL=cli.common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.common.d.ts","sourceRoot":"","sources":["../src/cli.common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAK3E,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,UAAU,EAChB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,yCAAyC,CAAC;AAIjD,2DAA2D;AAC3D,eAAO,MAAM,WAAW,QAAO,MAET,CAAC;AAEvB,uDAAuD;AACvD,eAAO,MAAM,MAAM,QAAsB,CAAC;AAI1C,kDAAkD;AAClD,eAAO,MAAM,aAAa,GAAI,GAAG,MAAM,KAAG,MAKzC,CAAC;AAEF,oDAAoD;AACpD,eAAO,MAAM,WAAW,GAAI,GAAG,MAAM,KAAG,MAKvC,CAAC;AAEF,wDAAwD;AACxD,eAAO,MAAM,SAAS,GAAI,GAAG,MAAM,KAAG,MAIrC,CAAC;AAIF,sDAAsD;AACtD,eAAO,MAAM,aAAa,mFAGzB,CAAC;AACF,qDAAqD;AACrD,eAAO,MAAM,YAAY,kFAGxB,CAAC;AACF,qDAAqD;AACrD,eAAO,MAAM,SAAS,wEAAyD,CAAC;AAChF,wCAAwC;AACxC,eAAO,MAAM,YAAY,kFAGP,CAAC;AACnB,qEAAqE;AACrE,eAAO,MAAM,WAAW,4EAKG,CAAC;AAC5B,sEAAsE;AACtE,eAAO,MAAM,WAAW,uEAEC,CAAC;AAC1B,wDAAwD;AACxD,eAAO,MAAM,SAAS,8EAGrB,CAAC;AACF,iDAAiD;AACjD,eAAO,MAAM,iBAAiB,uFAG7B,CAAC;AACF,6CAA6C;AAC7C,eAAO,MAAM,aAAa,mGAGa,CAAC;AACxC,oEAAoE;AACpE,eAAO,MAAM,QAAQ,0EAKE,CAAC;AAIxB,gDAAgD;AAChD,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,mEAAmE;AACnE,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD,0EAA0E;AAC1E,wBAAgB,OAAO,CAAC,CAAC,EAAE,UAAU,GAAG,UAAU,CASjD;AAED,iDAAiD;AACjD,wBAAgB,cAAc,CAAC,CAAC,EAAE,UAAU,GAAG,YAAY,CAQ1D;AAED,oFAAoF;AACpF,wBAAgB,WAAW,CAAC,CAAC,EAAE,UAAU,GAAG,iBAAiB,EAAE,CAiB9D;AAED,6DAA6D;AAC7D,wBAAsB,OAAO,CAAC,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAY1D;AAED,qFAAqF;AACrF,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAO1C;AAED,8EAA8E;AAC9E,wBAAsB,aAAa,CAAC,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBlE;AAED,gEAAgE;AAChE,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAWnD"}
@@ -0,0 +1,156 @@
1
+ import { InvalidArgumentError, Option } from "@commander-js/extra-typings";
2
+ import { readFileSync } from "node:fs";
3
+ import { dirname, resolve } from "node:path";
4
+ import { env, exit } from "node:process";
5
+ import { fileURLToPath } from "node:url";
6
+ import { fetchAllLocations, isSupercharger, } from "@mxpicture/teslamate-extended-api/api";
7
+ import { ingestSuperchargers, JsonFileStore, PostgresStore, } from "@mxpicture/teslamate-extended-api/store";
8
+ const __dirname = dirname(fileURLToPath(import.meta.url));
9
+ /** Reads the CLI package version from its package.json. */
10
+ export const readVersion = () => JSON.parse(readFileSync(resolve(__dirname, "../package.json"), "utf8"))
11
+ .version;
12
+ /** One day in milliseconds — the schedule interval. */
13
+ export const DAY_MS = 24 * 60 * 60 * 1000;
14
+ // ---------- argument parsers ----------
15
+ /** Parses a non-negative float (e.g. --delay). */
16
+ export const parseFloatArg = (v) => {
17
+ const n = Number(v);
18
+ if (!Number.isFinite(n) || n < 0)
19
+ throw new InvalidArgumentError("must be a non-negative number");
20
+ return n;
21
+ };
22
+ /** Parses a non-negative integer (e.g. --limit). */
23
+ export const parseIntArg = (v) => {
24
+ const n = parseInt(v, 10);
25
+ if (isNaN(n) || n < 0)
26
+ throw new InvalidArgumentError("must be a non-negative integer");
27
+ return n;
28
+ };
29
+ /** Validates an HH:MM (24h) time string (e.g. --at). */
30
+ export const parseTime = (v) => {
31
+ if (!/^([01]\d|2[0-3]):[0-5]\d$/.test(v))
32
+ throw new InvalidArgumentError("expected HH:MM (24h)");
33
+ return v;
34
+ };
35
+ // ---------- commander options ----------
36
+ /** Commander option: restrict to a single country. */
37
+ export const countryOption = new Option("-c, --country <name>", "Only this country");
38
+ /** Commander option: restrict to a single region. */
39
+ export const regionOption = new Option("-R, --region <name>", "Only this region");
40
+ /** Commander option: all Superchargers worldwide. */
41
+ export const allOption = new Option("-a, --all", "All Superchargers worldwide");
42
+ /** Commander option: pricing locale. */
43
+ export const localeOption = new Option("-l, --locale <locale>", "Locale for pricing").default("en-US");
44
+ /** Commander option: politeness delay between requests (seconds). */
45
+ export const delayOption = new Option("-d, --delay <seconds>", "Delay between requests")
46
+ .default(0.35)
47
+ .argParser(parseFloatArg);
48
+ /** Commander option: cap the number of sites fetched (0 = no cap). */
49
+ export const limitOption = new Option("-n, --limit <count>", "Cap number of sites")
50
+ .default(0)
51
+ .argParser(parseIntArg);
52
+ /** Commander option: JSON snapshot output directory. */
53
+ export const outOption = new Option("-o, --out <dir>", "Write JSON snapshots to this directory (env SUPERCHARGERS_OUT_DIR)");
54
+ /** Commander option: Postgres connection URL. */
55
+ export const postgresUrlOption = new Option("-p, --postgres-url <url>", "Append snapshots to this Postgres DB (env SUPERCHARGERS_PG_URL)");
56
+ /** Commander option: Postgres table name. */
57
+ export const pgTableOption = new Option("--pg-table <name>", "Postgres table name").default("supercharger_price_history");
58
+ /** Commander option: daily run time for `schedule` (24h, local). */
59
+ export const atOption = new Option("-t, --at <HH:MM>", "Daily run time (24h, local)")
60
+ .default("03:30")
61
+ .argParser(parseTime);
62
+ /** Resolves the single scope flag (exactly one of country/region/all). */
63
+ export function toScope(o) {
64
+ const picked = [o.country, o.region, o.all ? "all" : undefined].filter(Boolean);
65
+ if (picked.length !== 1) {
66
+ console.error("Pick exactly one scope: --country | --region | --all.");
67
+ exit(1);
68
+ }
69
+ return { country: o.country, region: o.region, all: o.all };
70
+ }
71
+ /** Maps CLI options to the api fetch options. */
72
+ export function toFetchOptions(o) {
73
+ return {
74
+ scope: toScope(o),
75
+ locale: o.locale,
76
+ delayMs: o.delay * 1000,
77
+ limit: o.limit,
78
+ logger: (m) => console.log(m),
79
+ };
80
+ }
81
+ /** Builds the sinks the user asked for (CLI flag or env). At least one required. */
82
+ export function buildStores(o) {
83
+ const stores = [];
84
+ const outDir = o.out ?? env.SUPERCHARGERS_OUT_DIR;
85
+ const pgUrl = o.postgresUrl ?? env.SUPERCHARGERS_PG_URL;
86
+ if (outDir)
87
+ stores.push(new JsonFileStore(outDir));
88
+ if (pgUrl)
89
+ stores.push(new PostgresStore({ connectionString: pgUrl, table: o.pgTable }));
90
+ if (stores.length === 0) {
91
+ console.error("No output configured. Pass --out <dir> and/or --postgres-url <url> " +
92
+ "(or set SUPERCHARGERS_OUT_DIR / SUPERCHARGERS_PG_URL).");
93
+ exit(1);
94
+ }
95
+ return stores;
96
+ }
97
+ /** Fetches one snapshot, stores it, and closes the sinks. */
98
+ export async function runOnce(o) {
99
+ const fetchOpts = toFetchOptions(o);
100
+ const stores = buildStores(o);
101
+ try {
102
+ const res = await ingestSuperchargers(fetchOpts, stores);
103
+ console.log(`Saved ${res.count} Superchargers (run ${res.runId}, ` +
104
+ `${res.fetchedAt.toISOString()}).`);
105
+ }
106
+ finally {
107
+ for (const s of stores)
108
+ await s.close?.();
109
+ }
110
+ }
111
+ /** ms from now until the next HH:MM (local); rolls to tomorrow if already passed. */
112
+ export function msUntil(at) {
113
+ const [h, m] = at.split(":").map(Number);
114
+ const now = new Date();
115
+ const next = new Date(now);
116
+ next.setHours(h, m, 0, 0);
117
+ if (next <= now)
118
+ next.setTime(next.getTime() + DAY_MS);
119
+ return next.getTime() - now.getTime();
120
+ }
121
+ /** Runs once on start, then every day at o.at — keeping the process alive. */
122
+ export async function scheduleDaily(o) {
123
+ const safeRun = async () => {
124
+ try {
125
+ await runOnce(o);
126
+ }
127
+ catch (e) {
128
+ console.error("Run failed:", e instanceof Error ? e.message : e);
129
+ }
130
+ };
131
+ const arm = () => {
132
+ const wait = msUntil(o.at);
133
+ console.log(`Next run at ${o.at} (in ${Math.round(wait / 60000)} min).`);
134
+ setTimeout(async () => {
135
+ await safeRun();
136
+ arm();
137
+ }, wait);
138
+ };
139
+ await safeRun(); // run immediately on start
140
+ arm();
141
+ }
142
+ /** Prints the countries and regions that have Superchargers. */
143
+ export async function listCountries() {
144
+ const locations = (await fetchAllLocations()).filter(isSupercharger);
145
+ const countries = [
146
+ ...new Set(locations.map((l) => l.country).filter(Boolean)),
147
+ ].sort();
148
+ const regions = [
149
+ ...new Set(locations.map((l) => l.region).filter(Boolean)),
150
+ ].sort();
151
+ console.log("Regions:", regions.join(", "));
152
+ console.log("\nCountries:");
153
+ for (const c of countries)
154
+ console.log(" ", c);
155
+ }
156
+ //# sourceMappingURL=cli.common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.common.js","sourceRoot":"","sources":["../src/cli.common.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * teslamate-superchargers
4
+ * =======================
5
+ * Fetch all Tesla Supercharger locations + pricing (via the public tesla.com
6
+ * endpoints, see `@mxpicture/teslamate-extended-api`) and persist each run as a
7
+ * dated snapshot — to JSON files and/or PostgreSQL. Because every run is stored
8
+ * under its own timestamp, repeated runs build a price history.
9
+ *
10
+ * teslamate-superchargers fetch --all --out ./data --postgres-url "$PG_URL"
11
+ * teslamate-superchargers schedule --all --postgres-url "$PG_URL" --at 03:30
12
+ * teslamate-superchargers list-countries
13
+ *
14
+ * The `schedule` command runs once on start and then daily at --at, keeping the
15
+ * process alive — so a single container is enough to refresh the data every day.
16
+ */
17
+ export {};
18
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;GAcG"}
package/dist/cli.js ADDED
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * teslamate-superchargers
4
+ * =======================
5
+ * Fetch all Tesla Supercharger locations + pricing (via the public tesla.com
6
+ * endpoints, see `@mxpicture/teslamate-extended-api`) and persist each run as a
7
+ * dated snapshot — to JSON files and/or PostgreSQL. Because every run is stored
8
+ * under its own timestamp, repeated runs build a price history.
9
+ *
10
+ * teslamate-superchargers fetch --all --out ./data --postgres-url "$PG_URL"
11
+ * teslamate-superchargers schedule --all --postgres-url "$PG_URL" --at 03:30
12
+ * teslamate-superchargers list-countries
13
+ *
14
+ * The `schedule` command runs once on start and then daily at --at, keeping the
15
+ * process alive — so a single container is enough to refresh the data every day.
16
+ */
17
+ import { program } from "@commander-js/extra-typings";
18
+ import { argv, exit } from "node:process";
19
+ import { allOption, atOption, countryOption, delayOption, limitOption, listCountries, localeOption, outOption, pgTableOption, postgresUrlOption, readVersion, regionOption, runOnce, scheduleDaily, } from "./cli.common.js";
20
+ program
21
+ .name("teslamate-superchargers")
22
+ .version(readVersion())
23
+ .description("Fetch + store Tesla Supercharger locations and pricing");
24
+ program
25
+ .command("fetch")
26
+ .description("Fetch one snapshot and store it, then exit")
27
+ .addOption(countryOption)
28
+ .addOption(regionOption)
29
+ .addOption(allOption)
30
+ .addOption(localeOption)
31
+ .addOption(delayOption)
32
+ .addOption(limitOption)
33
+ .addOption(outOption)
34
+ .addOption(postgresUrlOption)
35
+ .addOption(pgTableOption)
36
+ .action(async (o) => {
37
+ await runOnce(o);
38
+ });
39
+ program
40
+ .command("schedule")
41
+ .description("Fetch now, then refresh once a day at --at (keeps running)")
42
+ .addOption(countryOption)
43
+ .addOption(regionOption)
44
+ .addOption(allOption)
45
+ .addOption(localeOption)
46
+ .addOption(delayOption)
47
+ .addOption(limitOption)
48
+ .addOption(outOption)
49
+ .addOption(postgresUrlOption)
50
+ .addOption(pgTableOption)
51
+ .addOption(atOption)
52
+ .action(async (o) => {
53
+ await scheduleDaily(o);
54
+ });
55
+ program
56
+ .command("list-countries")
57
+ .description("List the countries and regions that have Superchargers")
58
+ .action(async () => {
59
+ await listCountries();
60
+ });
61
+ program.parseAsync(argv).catch((e) => {
62
+ console.error(e);
63
+ exit(1);
64
+ });
65
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EACL,SAAS,EACT,QAAQ,EACR,aAAa,EACb,WAAW,EACX,WAAW,EACX,aAAa,EACb,YAAY,EACZ,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,OAAO,EACP,aAAa,GACd,MAAM,iBAAiB,CAAC;AAEzB,OAAO;KACJ,IAAI,CAAC,yBAAyB,CAAC;KAC/B,OAAO,CAAC,WAAW,EAAE,CAAC;KACtB,WAAW,CAAC,wDAAwD,CAAC,CAAC;AAEzE,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,4CAA4C,CAAC;KACzD,SAAS,CAAC,aAAa,CAAC;KACxB,SAAS,CAAC,YAAY,CAAC;KACvB,SAAS,CAAC,SAAS,CAAC;KACpB,SAAS,CAAC,YAAY,CAAC;KACvB,SAAS,CAAC,WAAW,CAAC;KACtB,SAAS,CAAC,WAAW,CAAC;KACtB,SAAS,CAAC,SAAS,CAAC;KACpB,SAAS,CAAC,iBAAiB,CAAC;KAC5B,SAAS,CAAC,aAAa,CAAC;KACxB,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;IAClB,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;AACnB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,4DAA4D,CAAC;KACzE,SAAS,CAAC,aAAa,CAAC;KACxB,SAAS,CAAC,YAAY,CAAC;KACvB,SAAS,CAAC,SAAS,CAAC;KACpB,SAAS,CAAC,YAAY,CAAC;KACvB,SAAS,CAAC,WAAW,CAAC;KACtB,SAAS,CAAC,WAAW,CAAC;KACtB,SAAS,CAAC,SAAS,CAAC;KACpB,SAAS,CAAC,iBAAiB,CAAC;KAC5B,SAAS,CAAC,aAAa,CAAC;KACxB,SAAS,CAAC,QAAQ,CAAC;KACnB,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;IAClB,MAAM,aAAa,CAAC,CAAC,CAAC,CAAC;AACzB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,wDAAwD,CAAC;KACrE,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,aAAa,EAAE,CAAC;AACxB,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IACnC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjB,IAAI,CAAC,CAAC,CAAC,CAAC;AACV,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./cli.common.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -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,2 @@
1
+ export * from "./cli.common.js";
2
+ //# sourceMappingURL=index.js.map
@@ -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,46 @@
1
+ {
2
+ "name": "@mxpicture/teslamate-extended-cli",
3
+ "version": "2.1.51",
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-teslamate-extended.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
+ },
33
+ "publishConfig": {
34
+ "access": "public"
35
+ },
36
+ "dependencies": {
37
+ "@commander-js/extra-typings": "^14.0.0",
38
+ "@mxpicture/teslamate-extended-api": "^2.1.51",
39
+ "commander": "^14.0.3"
40
+ },
41
+ "devDependencies": {
42
+ "@types/node": "^25.2.3",
43
+ "eslint": "^9.39.3",
44
+ "typescript": "^5.9.3"
45
+ }
46
+ }