@mxpicture/tesla-superchargers-api 0.1.3 → 0.1.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.
Files changed (53) hide show
  1. package/dist/api/ChargersApi.d.ts +1 -1
  2. package/dist/api/ChargersApi.d.ts.map +1 -1
  3. package/dist/api/ChargersApi.js +6 -17
  4. package/dist/api/ChargersApi.js.map +1 -1
  5. package/dist/api/InvoicesApi.d.ts +27 -0
  6. package/dist/api/InvoicesApi.d.ts.map +1 -0
  7. package/dist/api/InvoicesApi.js +94 -0
  8. package/dist/api/InvoicesApi.js.map +1 -0
  9. package/dist/api/SlugsApi.d.ts +1 -1
  10. package/dist/api/SlugsApi.d.ts.map +1 -1
  11. package/dist/api/SlugsApi.js +4 -15
  12. package/dist/api/SlugsApi.js.map +1 -1
  13. package/dist/api/index.d.ts +1 -0
  14. package/dist/api/index.d.ts.map +1 -1
  15. package/dist/api/index.js +1 -0
  16. package/dist/api/index.js.map +1 -1
  17. package/dist/common/index.d.ts +1 -0
  18. package/dist/common/index.d.ts.map +1 -1
  19. package/dist/common/index.js +1 -0
  20. package/dist/common/index.js.map +1 -1
  21. package/dist/common/invoicesCsv.common.d.ts +87 -0
  22. package/dist/common/invoicesCsv.common.d.ts.map +1 -0
  23. package/dist/common/invoicesCsv.common.js +193 -0
  24. package/dist/common/invoicesCsv.common.js.map +1 -0
  25. package/dist/common/sync.common.d.ts +1 -48
  26. package/dist/common/sync.common.d.ts.map +1 -1
  27. package/dist/common/sync.common.js +1 -97
  28. package/dist/common/sync.common.js.map +1 -1
  29. package/dist/sync/ChargersSync.d.ts +13 -0
  30. package/dist/sync/ChargersSync.d.ts.map +1 -0
  31. package/dist/sync/ChargersSync.js +25 -0
  32. package/dist/sync/ChargersSync.js.map +1 -0
  33. package/dist/sync/ISyncHandler.d.ts +40 -0
  34. package/dist/sync/ISyncHandler.d.ts.map +1 -0
  35. package/dist/sync/ISyncHandler.js +67 -0
  36. package/dist/sync/ISyncHandler.js.map +1 -0
  37. package/dist/sync/ISyncPlanHandler.d.ts +25 -0
  38. package/dist/sync/ISyncPlanHandler.d.ts.map +1 -0
  39. package/dist/sync/ISyncPlanHandler.js +62 -0
  40. package/dist/sync/ISyncPlanHandler.js.map +1 -0
  41. package/dist/sync/InvoicesSync.d.ts +8 -0
  42. package/dist/sync/InvoicesSync.d.ts.map +1 -0
  43. package/dist/sync/InvoicesSync.js +21 -0
  44. package/dist/sync/InvoicesSync.js.map +1 -0
  45. package/dist/sync/SlugsSync.d.ts +9 -0
  46. package/dist/sync/SlugsSync.d.ts.map +1 -0
  47. package/dist/sync/SlugsSync.js +18 -0
  48. package/dist/sync/SlugsSync.js.map +1 -0
  49. package/dist/sync/index.d.ts +6 -0
  50. package/dist/sync/index.d.ts.map +1 -0
  51. package/dist/sync/index.js +7 -0
  52. package/dist/sync/index.js.map +1 -0
  53. package/package.json +11 -4
@@ -47,7 +47,7 @@ export declare class ChargersApi extends IApi {
47
47
  syncLoad(slug: string, locale: string, slugsId?: PicSlugsId): Promise<PicChargers>;
48
48
  /** Snapshot sync from a full-feed file dump. Does not touch pricebooks. */
49
49
  syncLoadFile(path: string): Promise<SyncSummary>;
50
- protected _syncLoad(clientDocs: TeslaClientCharger[]): Promise<SyncSummary>;
50
+ protected _syncLoad(docs: TeslaClientCharger[]): Promise<SyncSummary>;
51
51
  }
52
52
  export declare const chargersApi: () => ChargersApi;
53
53
  //# sourceMappingURL=ChargersApi.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChargersApi.d.ts","sourceRoot":"","sources":["../../src/api/ChargersApi.ts"],"names":[],"mappings":"AAOA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,UAAU,EAChB,MAAM,iDAAiD,CAAC;AACzD,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,4CAA4C,CAAC;AAOpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4CAA4C,CAAC;AAQhF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAO1D,qBAAa,WAAY,SAAQ,IAAI;IACnC;;;;;;;;;;OAUG;IACU,IAAI,CACf,IAAI,EAAE,aAAa,EACnB,MAAM,GAAE,MAAgB,GACvB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IA8D9B;;;;;;;;;;;;;;;OAeG;IACU,UAAU,CACrB,IAAI,EAAE,aAAa,EACnB,EAAE,EAAE,IAAI,GACP,OAAO,CAAC,aAAa,EAAE,CAAC;IAmBd,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUzD;;;;;;;;;OASG;IACU,QAAQ,CACnB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,UAAU,GACnB,OAAO,CAAC,WAAW,CAAC;IAgDvB,2EAA2E;IAC9D,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;cAK7C,SAAS,CACvB,UAAU,EAAE,kBAAkB,EAAE,GAC/B,OAAO,CAAC,WAAW,CAAC;CAkBxB;AAGD,eAAO,MAAM,WAAW,mBAAqC,CAAC"}
1
+ {"version":3,"file":"ChargersApi.d.ts","sourceRoot":"","sources":["../../src/api/ChargersApi.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,UAAU,EAChB,MAAM,iDAAiD,CAAC;AACzD,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,4CAA4C,CAAC;AAOpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4CAA4C,CAAC;AAOhF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAO1D,qBAAa,WAAY,SAAQ,IAAI;IACnC;;;;;;;;;;OAUG;IACU,IAAI,CACf,IAAI,EAAE,aAAa,EACnB,MAAM,GAAE,MAAgB,GACvB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IA8D9B;;;;;;;;;;;;;;;OAeG;IACU,UAAU,CACrB,IAAI,EAAE,aAAa,EACnB,EAAE,EAAE,IAAI,GACP,OAAO,CAAC,aAAa,EAAE,CAAC;IAmBd,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUzD;;;;;;;;;OASG;IACU,QAAQ,CACnB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,UAAU,GACnB,OAAO,CAAC,WAAW,CAAC;IAgDvB,2EAA2E;IAC9D,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;cAK7C,SAAS,CAAC,IAAI,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;CAK5E;AAGD,eAAO,MAAM,WAAW,mBAAqC,CAAC"}
@@ -1,13 +1,13 @@
1
1
  import { createMeta, chargerToInitializer, pricebookToInitializer, } from "@mxpicture/tesla-superchargers-mate/transform";
2
2
  import { readFile } from "node:fs/promises";
3
3
  import json5 from "json5";
4
- import { picChargersInitializerKeys, } from "@mxpicture/tesla-superchargers-generated/public";
4
+ import {} from "@mxpicture/tesla-superchargers-generated/public";
5
5
  import { teslaClient, teslaClientChargersSchema, } from "@mxpicture/tesla-superchargers-mate/client";
6
6
  import { picChargersStore, picPricebooksStore, picSlugsStore, transaction, } from "@mxpicture/tesla-superchargers-mate/store";
7
- import { FAILURE_DEPRIORITIZE_THRESHOLD, isFresh, MAX_CHARGER_FETCHES, withoutFkColumns, } from "../common/chargers.common.js";
7
+ import { FAILURE_DEPRIORITIZE_THRESHOLD, isFresh, MAX_CHARGER_FETCHES, } from "../common/chargers.common.js";
8
8
  import { IApi } from "./IApi.js";
9
- import { syncColumns, syncSnapshot } from "../common/sync.common.js";
10
9
  import { pricebookCoversInstant, samePricebookGroup, } from "../common/pricebooks.common.js";
10
+ import { ChargersSync } from "../sync/ChargersSync.js";
11
11
  export class ChargersApi extends IApi {
12
12
  /**
13
13
  * Find the Supercharger at a coordinate: try the nearby slug rows
@@ -151,21 +151,10 @@ export class ChargersApi extends IApi {
151
151
  const json = json5.parse(await readFile(path, { encoding: "utf8" }));
152
152
  return await this._syncLoad(teslaClientChargersSchema.parse(json));
153
153
  }
154
- async _syncLoad(clientDocs) {
154
+ async _syncLoad(docs) {
155
155
  const meta = createMeta();
156
- const { compareColumns, updateColumns } = syncColumns(picChargersInitializerKeys);
157
- return await syncSnapshot({
158
- store: picChargersStore(),
159
- clientDocs,
160
- meta,
161
- toInitializer: (charger) => chargerToInitializer({ charger, meta }),
162
- keyOfInit: (doc) => doc.location_guid,
163
- keyOfDb: (doc) => doc.location_guid,
164
- deleteAbsent: "soft",
165
- conflictColumn: "location_guid",
166
- compareColumns: withoutFkColumns(compareColumns),
167
- updateColumns: withoutFkColumns(updateColumns),
168
- });
156
+ const sync = new ChargersSync();
157
+ return await sync.snapshot({ docs, meta });
169
158
  }
170
159
  }
171
160
  let _api = null;
@@ -1 +1 @@
1
- {"version":3,"file":"ChargersApi.js","sourceRoot":"","sources":["../../src/api/ChargersApi.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChargersApi.js","sourceRoot":"","sources":["../../src/api/ChargersApi.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAIN,MAAM,iDAAiD,CAAC;AACzD,OAAO,EACL,WAAW,EACX,yBAAyB,GAE1B,MAAM,4CAA4C,CAAC;AACpD,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,WAAW,GACZ,MAAM,2CAA2C,CAAC;AAGnD,OAAO,EACL,8BAA8B,EAC9B,OAAO,EACP,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EACL,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,MAAM,OAAO,WAAY,SAAQ,IAAI;IACnC;;;;;;;;;;OAUG;IACI,KAAK,CAAC,IAAI,CACf,IAAmB,EACnB,SAAiB,OAAO;QAExB,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAC5D,MAAM,UAAU,GAAuB,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC5D,IAAI,EAAE,KAAK,CAAC,iBAAiB;YAC7B,OAAO,EAAE,KAAK,CAAC,EAAE;YACjB,YAAY,EAAE,KAAK,CAAC,aAAa;SAClC,CAAC,CAAC,CAAC;QACJ,qEAAqE;QACrE,iDAAiD;QACjD,UAAU,CAAC,IAAI,CACb,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,MAAM,CAAC,CAAC,CAAC,YAAY,IAAI,8BAA8B,CAAC;YACxD,MAAM,CAAC,CAAC,CAAC,YAAY,IAAI,8BAA8B,CAAC,CAC3D,CAAC;QAEF,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;QACzC,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;QAEnC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC;gBAAE,SAAS;YACvC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAEzB,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAChE,IAAI,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;gBAAE,OAAO,MAAM,CAAC;YAE7C,IAAI,OAAO,IAAI,mBAAmB,EAAE,CAAC;gBACnC,IAAI,MAAM;oBAAE,OAAO,MAAM,CAAC,CAAC,sBAAsB;gBACjD,SAAS;YACX,CAAC;YACD,OAAO,EAAE,CAAC;YACV,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CACjC,SAAS,CAAC,IAAI,EACd,MAAM,EACN,SAAS,CAAC,OAAO,CAClB,CAAC;gBAEF,IAAI,OAAO,CAAC,aAAa,GAAG,CAAC;oBAC3B,MAAM,aAAa,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBAE9C,MAAM,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;gBAEhD,OAAO,OAAO,CAAC;YACjB,CAAC;YAAC,MAAM,CAAC;gBACP,gEAAgE;gBAChE,oDAAoD;gBACpD,IAAI,MAAM,EAAE,CAAC;oBACX,MAAM,CAAC,aAAa,GAAG,MAAM,aAAa,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;oBACtE,OAAO,MAAM,CAAC,CAAC,sBAAsB;gBACvC,CAAC;gBAED,SAAS,CAAC,YAAY,GAAG,MAAM,UAAU,CAAC,eAAe,CACvD,SAAS,CAAC,OAAO,CAClB,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACI,KAAK,CAAC,UAAU,CACrB,IAAmB,EACnB,EAAQ;QAER,MAAM,MAAM,GAAG,CAAC,MAAM,gBAAgB,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QAC5E,IAAI,OAAO,GAAgB,MAAM,CAAC;QAClC,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,UAAU,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACzD,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC;QAC9C,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QAExB,MAAM,eAAe,GAAG,kBAAkB,EAAE,CAAC;QAE7C,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/D,MAAM,IAAI,GACR,KAAK,CAAC,MAAM,GAAG,CAAC;YACd,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,MAAM,eAAe,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACzD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CACzB,sBAAsB,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,CAAC,SAAS,CAAC,CACnD,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,eAAe,CAAC,IAAY;QACvC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QACrE,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAC1B,MAAM,IAAI,CAAC,cAAc,CACvB,gBAAgB,EAAE,EAClB,yBAAyB,CAAC,KAAK,CAAC,IAAI,CAAC,EACrC,CAAC,OAAO,EAAE,EAAE,CAAC,oBAAoB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CACrD,CAAC;IACJ,CAAC;IAED;;;;;;;;;OASG;IACI,KAAK,CAAC,QAAQ,CACnB,IAAY,EACZ,MAAc,EACd,OAAoB;QAEpB,MAAM,SAAS,GAAG,MAAM,WAAW,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACjE,IAAI,CAAC,SAAS,CAAC,OAAO;YACpB,MAAM,IAAI,KAAK,CACb,2BAA2B,IAAI,uBAAuB;gBACpD,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjD,KAAK,SAAS,CAAC,QAAQ,YAAY,CACtC,CAAC;QACJ,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC;QAClC,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,oBAAoB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9D,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;QACzC,MAAM,eAAe,GAAG,kBAAkB,EAAE,CAAC;QAE7C,OAAO,MAAM,WAAW,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;YACzD,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,SAAS,CACvC,IAAI;YACJ,qEAAqE;YACrE,8CAA8C;YAC9C,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EACrE,EAAE,CACH,CAAC;YACF,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YAClE,MAAM,IAAI,GAAG,OAAO,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CACzD,sBAAsB,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAChE,CAAC;YACF,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtB,+DAA+D;gBAC/D,mDAAmD;gBACnD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;oBACpB,OAAO,CAAC,IAAI,CACV,WAAW,GAAG,CAAC,EAAE,WAAW,IAAI,8DAA8D,CAC/F,CAAC;YACN,CAAC;iBAAM,IAAI,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;gBAC7C,oEAAoE;gBACpE,MAAM,eAAe,CAAC,oBAAoB,CACxC,GAAG,CAAC,EAAE,EACN,OAAO,CAAC,CAAC,CAAC,CAAC,eAAe,EAC1B,IAAI,CAAC,eAAe,EACpB,EAAE,CACH,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,MAAM,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC7C,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC,CAAC,CAAC;IACL,CAAC;IAED,2EAA2E;IACpE,KAAK,CAAC,YAAY,CAAC,IAAY;QACpC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QACrE,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,yBAAyB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACrE,CAAC;IAES,KAAK,CAAC,SAAS,CAAC,IAA0B;QAClD,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,IAAI,YAAY,EAAE,CAAC;QAChC,OAAO,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;CACF;AAED,IAAI,IAAI,GAAuB,IAAI,CAAC;AACpC,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,CAAC,IAAI,KAAK,IAAI,WAAW,EAAE,CAAC,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { type InvoicesCsv } from "../common/invoicesCsv.common.js";
2
+ import { IApi } from "./IApi.js";
3
+ import type { SyncSummary } from "../types/sync.types.js";
4
+ import type { Meta } from "@mxpicture/tesla-superchargers-mate/types";
5
+ import type { DropboxClient } from "@mxpicture/tesla-superchargers-cloud-store/client";
6
+ import type { DropboxEntry } from "@mxpicture/tesla-superchargers-cloud-store/types";
7
+ export declare class InvoicesApi extends IApi {
8
+ syncDropbox(): Promise<SyncSummary>;
9
+ /**
10
+ * Sync one dropbox entry: non-CSV entries and files already recorded in
11
+ * `pic_invoice_files` are skipped. A file is recorded only after all its
12
+ * rows landed — a failed file is logged and retried on the next run.
13
+ */
14
+ protected syncDropboxEntry(entry: DropboxEntry, client: DropboxClient, meta: Meta, storedNames: Set<string>): Promise<SyncSummary | null>;
15
+ /**
16
+ * Throws when any row fails validation, before touching the db — a file is
17
+ * imported completely or not at all, so a file recorded as synced never
18
+ * hides silently dropped rows. The exception are credit/free charges
19
+ * without an invoice number: they cannot be keyed, so they are skipped and
20
+ * reported via `feedNullKeys` instead of failing the file.
21
+ */
22
+ syncCsv(csvText: string): Promise<SyncSummary>;
23
+ syncCsvFile(path: string): Promise<SyncSummary>;
24
+ protected _syncLoad(csvs: InvoicesCsv[]): Promise<SyncSummary>;
25
+ }
26
+ export declare const invoicesApi: () => InvoicesApi;
27
+ //# sourceMappingURL=InvoicesApi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InvoicesApi.d.ts","sourceRoot":"","sources":["../../src/api/InvoicesApi.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAO1D,OAAO,KAAK,EAAW,IAAI,EAAE,MAAM,2CAA2C,CAAC;AAC/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mDAAmD,CAAC;AAEvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kDAAkD,CAAC;AAErF,qBAAa,WAAY,SAAQ,IAAI;IACtB,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;IAqChD;;;;OAIG;cACa,gBAAgB,CAC9B,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,GACvB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAmB9B;;;;;;OAMG;IACU,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAc9C,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;cAI5C,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;CAmBrE;AAGD,eAAO,MAAM,WAAW,mBAAqC,CAAC"}
@@ -0,0 +1,94 @@
1
+ import { formatInvoicesCsvErrors, fromInvoiceCsv, parseInvoicesCsv, } from "../common/invoicesCsv.common.js";
2
+ import { IApi } from "./IApi.js";
3
+ import { createMeta } from "@mxpicture/tesla-superchargers-mate/transform";
4
+ import { readFile } from "node:fs/promises";
5
+ import { InvoicesSync } from "../sync/InvoicesSync.js";
6
+ import { chargingProcessesStore, picInvoiceFilesStore, } from "@mxpicture/tesla-superchargers-mate/store";
7
+ import { dropboxClientByEnv } from "@mxpicture/tesla-superchargers-cloud-store/client";
8
+ export class InvoicesApi extends IApi {
9
+ async syncDropbox() {
10
+ const client = dropboxClientByEnv();
11
+ const entries = await client.fetchBaseDir();
12
+ const meta = createMeta();
13
+ const storedNames = new Set((await picInvoiceFilesStore().query()).map((file) => file.name.toLowerCase()));
14
+ const summary = {
15
+ feedCount: 0,
16
+ feedDuplicates: 0,
17
+ feedNullKeys: 0,
18
+ upserted: 0,
19
+ deleted: 0,
20
+ };
21
+ for (const entry of entries) {
22
+ const subSummary = await this.syncDropboxEntry(entry, client, meta, storedNames);
23
+ if (subSummary) {
24
+ summary.feedCount += subSummary.feedCount;
25
+ summary.feedDuplicates += subSummary.feedDuplicates;
26
+ summary.feedNullKeys += subSummary.feedNullKeys;
27
+ summary.upserted += subSummary.upserted;
28
+ summary.deleted += subSummary.deleted;
29
+ }
30
+ }
31
+ return summary;
32
+ }
33
+ /**
34
+ * Sync one dropbox entry: non-CSV entries and files already recorded in
35
+ * `pic_invoice_files` are skipped. A file is recorded only after all its
36
+ * rows landed — a failed file is logged and retried on the next run.
37
+ */
38
+ async syncDropboxEntry(entry, client, meta, storedNames) {
39
+ const nameLower = entry.name.toLowerCase();
40
+ if (!nameLower.endsWith(".csv"))
41
+ return null;
42
+ if (storedNames.has(nameLower))
43
+ return null;
44
+ try {
45
+ const file = await client.fetchFile(entry.path);
46
+ const summary = await this.syncCsv(file.content);
47
+ await picInvoiceFilesStore().insert({ ...meta, name: entry.name });
48
+ storedNames.add(nameLower);
49
+ return summary;
50
+ }
51
+ catch (error) {
52
+ console.warn(`invoices dropbox: sync of "${entry.name}" failed:`, error);
53
+ return null;
54
+ }
55
+ }
56
+ /**
57
+ * Throws when any row fails validation, before touching the db — a file is
58
+ * imported completely or not at all, so a file recorded as synced never
59
+ * hides silently dropped rows. The exception are credit/free charges
60
+ * without an invoice number: they cannot be keyed, so they are skipped and
61
+ * reported via `feedNullKeys` instead of failing the file.
62
+ */
63
+ async syncCsv(csvText) {
64
+ const { invoices, errors, nullInvoiceNumbers } = parseInvoicesCsv(csvText);
65
+ if (errors.length > 0)
66
+ throw new Error(`invoices CSV: ${errors.length} invalid row(s)\n` +
67
+ formatInvoicesCsvErrors(errors));
68
+ const summary = await this._syncLoad(invoices);
69
+ // skipped pre-parse, so mirror the plan's null-key accounting
70
+ summary.feedCount += nullInvoiceNumbers;
71
+ summary.feedNullKeys += nullInvoiceNumbers;
72
+ return summary;
73
+ }
74
+ async syncCsvFile(path) {
75
+ return await this.syncCsv(await readFile(path, { encoding: "utf8" }));
76
+ }
77
+ async _syncLoad(csvs) {
78
+ const cp = chargingProcessesStore();
79
+ const meta = createMeta();
80
+ const docs = [];
81
+ for (const csv of csvs) {
82
+ const chargingProcessesId = await cp.lookupChargingProcessId(csv.Vin, csv.ChargeStartDateTime);
83
+ docs.push({ ...fromInvoiceCsv({ csv, meta }), chargingProcessesId });
84
+ }
85
+ const sync = new InvoicesSync();
86
+ return await sync.snapshot({
87
+ docs,
88
+ meta,
89
+ });
90
+ }
91
+ }
92
+ let _api = null;
93
+ export const invoicesApi = () => (_api ??= new InvoicesApi());
94
+ //# sourceMappingURL=InvoicesApi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InvoicesApi.js","sourceRoot":"","sources":["../../src/api/InvoicesApi.ts"],"names":[],"mappings":"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"}
@@ -9,7 +9,7 @@ export declare class SlugsApi extends IApi {
9
9
  initialLoadFile(path: string): Promise<SyncSummary>;
10
10
  syncLoad(): Promise<SyncSummary>;
11
11
  syncLoadFile(path: string): Promise<SyncSummary>;
12
- protected _syncLoad(clientDocs: TeslaClientSlug[]): Promise<SyncSummary>;
12
+ protected _syncLoad(docs: TeslaClientSlug[]): Promise<SyncSummary>;
13
13
  }
14
14
  export declare const slugsApi: () => SlugsApi;
15
15
  //# sourceMappingURL=SlugsApi.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SlugsApi.d.ts","sourceRoot":"","sources":["../../src/api/SlugsApi.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAClF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4CAA4C,CAAC;AAChF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAClF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAY1D,qBAAa,QAAS,SAAQ,IAAI;IACnB,IAAI,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAItD,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;IAgBnC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAgBnD,QAAQ,IAAI,OAAO,CAAC,WAAW,CAAC;IAKhC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;cAI7C,SAAS,CACvB,UAAU,EAAE,eAAe,EAAE,GAC5B,OAAO,CAAC,WAAW,CAAC;CAexB;AAGD,eAAO,MAAM,QAAQ,gBAAkC,CAAC"}
1
+ {"version":3,"file":"SlugsApi.d.ts","sourceRoot":"","sources":["../../src/api/SlugsApi.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAClF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4CAA4C,CAAC;AAChF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAClF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAY1D,qBAAa,QAAS,SAAQ,IAAI;IACnB,IAAI,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAItD,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;IAgBnC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAgBnD,QAAQ,IAAI,OAAO,CAAC,WAAW,CAAC;IAKhC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;cAI7C,SAAS,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;CAKzE;AAGD,eAAO,MAAM,QAAQ,gBAAkC,CAAC"}
@@ -2,10 +2,9 @@ import { parseTeslaClientSlugs, teslaClient, } from "@mxpicture/tesla-supercharg
2
2
  import { createMeta, slugToInitializer, } from "@mxpicture/tesla-superchargers-mate/transform";
3
3
  import { readFile } from "node:fs/promises";
4
4
  import json5 from "json5";
5
- import { picSlugsInitializerKeys } from "@mxpicture/tesla-superchargers-generated/public";
6
5
  import { picSlugsStore } from "@mxpicture/tesla-superchargers-mate/store";
7
6
  import { IApi } from "./IApi.js";
8
- import { syncSnapshot, syncColumns } from "../common/sync.common.js";
7
+ import { SlugsSync } from "../sync/SlugsSync.js";
9
8
  /** Per-element parse of a slugs file dump; invalid entries are skipped, not fatal. */
10
9
  const readSlugsFile = async (path) => {
11
10
  const json = json5.parse(await readFile(path, { encoding: "utf8" }));
@@ -47,20 +46,10 @@ export class SlugsApi extends IApi {
47
46
  async syncLoadFile(path) {
48
47
  return await this._syncLoad(await readSlugsFile(path));
49
48
  }
50
- async _syncLoad(clientDocs) {
49
+ async _syncLoad(docs) {
51
50
  const meta = createMeta();
52
- return await syncSnapshot({
53
- store: picSlugsStore(),
54
- clientDocs,
55
- meta,
56
- toInitializer: (slug) => slugToInitializer({ slug, meta }),
57
- keyOfInit: (doc) => doc.tesla_uuid ?? null,
58
- keyOfDb: (doc) => doc.tesla_uuid,
59
- // the table mirrors the feed: rows absent from it are hard-deleted
60
- deleteAbsent: "hard",
61
- conflictColumn: "tesla_uuid",
62
- ...syncColumns(picSlugsInitializerKeys),
63
- });
51
+ const sync = new SlugsSync();
52
+ return await sync.snapshot({ docs, meta });
64
53
  }
65
54
  }
66
55
  let _api = null;
@@ -1 +1 @@
1
- {"version":3,"file":"SlugsApi.js","sourceRoot":"","sources":["../../src/api/SlugsApi.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SlugsApi.js","sourceRoot":"","sources":["../../src/api/SlugsApi.ts"],"names":[],"mappings":"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"}
@@ -2,5 +2,6 @@ export * from "./ChargersApi.js";
2
2
  export * from "./ChargingProcessesApi.js";
3
3
  export * from "./FailuresApi.js";
4
4
  export * from "./IApi.js";
5
+ export * from "./InvoicesApi.js";
5
6
  export * from "./SlugsApi.js";
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC"}
package/dist/api/index.js CHANGED
@@ -3,5 +3,6 @@ export * from "./ChargersApi.js";
3
3
  export * from "./ChargingProcessesApi.js";
4
4
  export * from "./FailuresApi.js";
5
5
  export * from "./IApi.js";
6
+ export * from "./InvoicesApi.js";
6
7
  export * from "./SlugsApi.js";
7
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC"}
@@ -1,5 +1,6 @@
1
1
  export * from "./chargers.common.js";
2
2
  export * from "./failures.common.js";
3
+ export * from "./invoicesCsv.common.js";
3
4
  export * from "./pricebooks.common.js";
4
5
  export * from "./pushover.common.js";
5
6
  export * from "./sync.common.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/common/index.ts"],"names":[],"mappings":"AACA,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/common/index.ts"],"names":[],"mappings":"AACA,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC"}
@@ -1,6 +1,7 @@
1
1
  // This file is auto-generated by build-cli. Do not edit manually.
2
2
  export * from "./chargers.common.js";
3
3
  export * from "./failures.common.js";
4
+ export * from "./invoicesCsv.common.js";
4
5
  export * from "./pricebooks.common.js";
5
6
  export * from "./pushover.common.js";
6
7
  export * from "./sync.common.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/common/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/common/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Tesla charging-CSV import for pic_invoices.
3
+ *
4
+ * Pipeline: raw CSV string
5
+ * → csv-parse (structure: delimiters, quoting, headers)
6
+ * → zod row schema (semantics: "N/A" → null, "22.1285 kwh" → value+unit,
7
+ * "0.51/kwh" → value+unit, NUMERIC precision checks, ISO dates)
8
+ * → PicInvoicesInitializer
9
+ * → parameterized INSERT (numerics stay strings; pg casts to NUMERIC losslessly)
10
+ *
11
+ * deps: npm i csv-parse postgres zod
12
+ */
13
+ import type { Invoice, Meta } from "@mxpicture/tesla-superchargers-mate/types";
14
+ import { z } from "zod";
15
+ export declare const invoicesCsvSchema: z.ZodObject<{
16
+ ChargeStartDateTime: z.ZodPipe<z.ZodString, z.ZodTransform<Date, string>>;
17
+ Name: z.ZodPreprocess<z.ZodNullable<z.ZodString>>;
18
+ Vin: z.ZodString;
19
+ Model: z.ZodPreprocess<z.ZodNullable<z.ZodString>>;
20
+ Country: z.ZodString;
21
+ SiteLocationName: z.ZodString;
22
+ Description: z.ZodPreprocess<z.ZodNullable<z.ZodString>>;
23
+ QuantityBase: z.ZodPipe<z.ZodString, z.ZodTransform<{
24
+ value: number;
25
+ unit: string;
26
+ }, string>>;
27
+ QuantityTier1: z.ZodPreprocess<z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<{
28
+ value: number;
29
+ unit: string;
30
+ }, string>>>>;
31
+ QuantityTier2: z.ZodPreprocess<z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<{
32
+ value: number;
33
+ unit: string;
34
+ }, string>>>>;
35
+ QuantityTier3: z.ZodPreprocess<z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<{
36
+ value: number;
37
+ unit: string;
38
+ }, string>>>>;
39
+ QuantityTier4: z.ZodPreprocess<z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<{
40
+ value: number;
41
+ unit: string;
42
+ }, string>>>>;
43
+ InvoiceNumber: z.ZodString;
44
+ UnitCostBase: z.ZodPipe<z.ZodString, z.ZodTransform<{
45
+ value: number;
46
+ unit: string;
47
+ }, string>>;
48
+ UnitCostTier1: z.ZodPreprocess<z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<{
49
+ value: number;
50
+ unit: string;
51
+ }, string>>>>;
52
+ UnitCostTier2: z.ZodPreprocess<z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<{
53
+ value: number;
54
+ unit: string;
55
+ }, string>>>>;
56
+ UnitCostTier3: z.ZodPreprocess<z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<{
57
+ value: number;
58
+ unit: string;
59
+ }, string>>>>;
60
+ UnitCostTier4: z.ZodPreprocess<z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<{
61
+ value: number;
62
+ unit: string;
63
+ }, string>>>>;
64
+ VAT: z.ZodString;
65
+ "Total Exc. VAT": z.ZodString;
66
+ "Total Inc. VAT": z.ZodString;
67
+ Status: z.ZodPreprocess<z.ZodNullable<z.ZodString>>;
68
+ Invoice: z.ZodPreprocess<z.ZodNullable<z.ZodString>>;
69
+ }, z.core.$strip>;
70
+ export type InvoicesCsv = z.infer<typeof invoicesCsvSchema>;
71
+ export interface InvoicesCsvError {
72
+ line: number;
73
+ issues: z.core.$ZodIssue[];
74
+ }
75
+ /** One line per invalid row: `line 3: QuantityBase: invalid quantity: "x"`. */
76
+ export declare const formatInvoicesCsvErrors: (errors: InvoicesCsvError[]) => string;
77
+ export declare const parseInvoicesCsv: (csvText: string) => {
78
+ invoices: InvoicesCsv[];
79
+ errors: InvoicesCsvError[];
80
+ /** rows without an invoice number (credit/free charges) — skipped, not errors */
81
+ nullInvoiceNumbers: number;
82
+ };
83
+ export declare const fromInvoiceCsv: ({ csv, meta, }: {
84
+ csv: InvoicesCsv;
85
+ meta: Meta;
86
+ }) => Invoice;
87
+ //# sourceMappingURL=invoicesCsv.common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoicesCsv.common.d.ts","sourceRoot":"","sources":["../../src/common/invoicesCsv.common.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EACV,OAAO,EAEP,IAAI,EACL,MAAM,2CAA2C,CAAC;AAEnD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAmGxB,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwB5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAM5D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;CAC5B;AAED,+EAA+E;AAC/E,eAAO,MAAM,uBAAuB,GAAI,QAAQ,gBAAgB,EAAE,KAAG,MAQtD,CAAC;AAEhB,eAAO,MAAM,gBAAgB,GAC3B,SAAS,MAAM,KACd;IACD,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,iFAAiF;IACjF,kBAAkB,EAAE,MAAM,CAAC;CA4B5B,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,gBAG5B;IACD,GAAG,EAAE,WAAW,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;CACZ,KAAG,OAgCH,CAAC"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Tesla charging-CSV import for pic_invoices.
3
+ *
4
+ * Pipeline: raw CSV string
5
+ * → csv-parse (structure: delimiters, quoting, headers)
6
+ * → zod row schema (semantics: "N/A" → null, "22.1285 kwh" → value+unit,
7
+ * "0.51/kwh" → value+unit, NUMERIC precision checks, ISO dates)
8
+ * → PicInvoicesInitializer
9
+ * → parameterized INSERT (numerics stay strings; pg casts to NUMERIC losslessly)
10
+ *
11
+ * deps: npm i csv-parse postgres zod
12
+ */
13
+ import { removeUndefined } from "@mxpicture/tesla-superchargers-mate/transform";
14
+ import { parse } from "csv-parse/sync";
15
+ import { z } from "zod";
16
+ /* ------------------------------------------------------------------ */
17
+ /* helpers */
18
+ /* ------------------------------------------------------------------ */
19
+ const castNum = (name, str) => {
20
+ const value = str === null ? str : Number(str);
21
+ if (value === null || !Number.isFinite(value))
22
+ throw new Error(`invalid ${name}: "${str}"`);
23
+ return value;
24
+ };
25
+ /** "N/A" / "" / whitespace → null, everything else → trimmed string. */
26
+ const naToNull = (v) => {
27
+ if (typeof v !== "string")
28
+ return v;
29
+ const t = v.trim();
30
+ return t === "" || t.toUpperCase() === "N/A" ? null : t;
31
+ };
32
+ /**
33
+ * Decimal kept as *string* (matches Kanel's typing of pg NUMERIC) with a
34
+ * precision/scale check mirroring the column definition, so bad values fail
35
+ * in validation instead of as a pg error mid-insert.
36
+ */
37
+ const numericString = (precision, scale) => z
38
+ .string()
39
+ .trim()
40
+ .regex(/^-?\d+(\.\d+)?$/, "not a decimal number")
41
+ .refine((s) => {
42
+ const [int = "", frac = ""] = s.replace("-", "").split(".");
43
+ return frac.length <= scale && int.length <= precision - scale;
44
+ }, `exceeds NUMERIC(${precision}, ${scale})`);
45
+ /** "22.1285 kwh" → { value: 22.1285, unit: "kwh" } (unit optional). */
46
+ const quantity = z
47
+ .string()
48
+ .trim()
49
+ .transform((s, ctx) => {
50
+ const m = s.match(/^(-?\d+(?:\.\d+)?)(?:\s+(\S+))?$/);
51
+ if (!m) {
52
+ ctx.addIssue({ code: "custom", message: `invalid quantity: "${s}"` });
53
+ return z.NEVER;
54
+ }
55
+ const value = m[1] === null ? m[1] : Number(m[1]);
56
+ if (value === null || !Number.isFinite(value)) {
57
+ ctx.addIssue({ code: "custom", message: `invalid quantity: "${s}"` });
58
+ return z.NEVER;
59
+ }
60
+ return { value, unit: m[2]?.toLowerCase() ?? null };
61
+ })
62
+ .refine((q) => numericString(8, 4).safeParse(String(q.value)).success, {
63
+ message: "quantity exceeds NUMERIC(8, 4)",
64
+ });
65
+ /** "0.51/kwh" → { value: 0.51, unit: "kwh" }. */
66
+ const unitCost = z
67
+ .string()
68
+ .trim()
69
+ .transform((s, ctx) => {
70
+ const m = s.match(/^(-?\d+(?:\.\d+)?)\s*\/\s*(\S+)$/);
71
+ if (!m) {
72
+ ctx.addIssue({ code: "custom", message: `invalid unit cost: "${s}"` });
73
+ return z.NEVER;
74
+ }
75
+ const value = m[1] === null ? m[1] : Number(m[1]);
76
+ if (value === null || !Number.isFinite(value)) {
77
+ ctx.addIssue({ code: "custom", message: `invalid unit cost: "${s}"` });
78
+ return z.NEVER;
79
+ }
80
+ return { value, unit: m[2].toLowerCase() };
81
+ })
82
+ .refine((c) => numericString(4, 2).safeParse(String(c.value)).success, {
83
+ message: "unit cost exceeds NUMERIC(4, 2)",
84
+ });
85
+ /** ISO-8601 with offset ("2026-03-31T14:56:00+02:00") → Date. */
86
+ const isoDate = z
87
+ .string()
88
+ .trim()
89
+ .transform((s, ctx) => {
90
+ const d = new Date(s);
91
+ if (Number.isNaN(d.getTime())) {
92
+ ctx.addIssue({ code: "custom", message: `invalid date: "${s}"` });
93
+ return z.NEVER;
94
+ }
95
+ return d;
96
+ });
97
+ const nullable = (schema) => z.preprocess(naToNull, schema.nullable());
98
+ const nonEmpty = z.string().trim().min(1);
99
+ /* ------------------------------------------------------------------ */
100
+ /* CSV row schema (keys = exact CSV headers) */
101
+ /* ------------------------------------------------------------------ */
102
+ export const invoicesCsvSchema = z.object({
103
+ ChargeStartDateTime: isoDate,
104
+ Name: nullable(nonEmpty),
105
+ Vin: nonEmpty,
106
+ Model: nullable(nonEmpty),
107
+ Country: nonEmpty,
108
+ SiteLocationName: nonEmpty,
109
+ Description: nullable(nonEmpty),
110
+ QuantityBase: quantity,
111
+ QuantityTier1: nullable(quantity),
112
+ QuantityTier2: nullable(quantity),
113
+ QuantityTier3: nullable(quantity),
114
+ QuantityTier4: nullable(quantity),
115
+ InvoiceNumber: nonEmpty,
116
+ UnitCostBase: unitCost,
117
+ UnitCostTier1: nullable(unitCost),
118
+ UnitCostTier2: nullable(unitCost),
119
+ UnitCostTier3: nullable(unitCost),
120
+ UnitCostTier4: nullable(unitCost),
121
+ VAT: numericString(5, 2),
122
+ "Total Exc. VAT": numericString(5, 2),
123
+ "Total Inc. VAT": numericString(5, 2),
124
+ Status: nullable(nonEmpty),
125
+ Invoice: nullable(z.string().trim().url()),
126
+ });
127
+ /** One line per invalid row: `line 3: QuantityBase: invalid quantity: "x"`. */
128
+ export const formatInvoicesCsvErrors = (errors) => errors
129
+ .map(({ line, issues }) => `line ${line}: ${issues
130
+ .map((issue) => `${issue.path.join(".")}: ${issue.message}`)
131
+ .join("; ")}`)
132
+ .join("\n");
133
+ export const parseInvoicesCsv = (csvText) => {
134
+ // csv-parse handles quoting ("Windischeschenbach, Germany"), BOM, CRLF.
135
+ const records = parse(csvText, {
136
+ columns: true, // first line = header, rows become objects
137
+ bom: true,
138
+ skip_empty_lines: true,
139
+ trim: true,
140
+ });
141
+ const invoices = [];
142
+ const errors = [];
143
+ let nullInvoiceNumbers = 0;
144
+ records.forEach((record, i) => {
145
+ // Credit/free charges ("CHARGING : CREDIT", €0.00) come without an
146
+ // invoice number. They cannot be keyed on invoice_number, so they are
147
+ // counted and skipped instead of failing the whole file.
148
+ if (naToNull(record.InvoiceNumber) === null) {
149
+ nullInvoiceNumbers++;
150
+ return;
151
+ }
152
+ const result = invoicesCsvSchema.safeParse(record);
153
+ if (result.success)
154
+ invoices.push(result.data);
155
+ else
156
+ errors.push({ line: i + 2, issues: result.error.issues });
157
+ });
158
+ return { invoices, errors, nullInvoiceNumbers };
159
+ };
160
+ export const fromInvoiceCsv = ({ csv, meta, }) => {
161
+ const result = {
162
+ id: undefined,
163
+ chargingProcessesId: null,
164
+ fetched_at: meta.fetched_at,
165
+ last_fetch_uuid: meta.last_fetch_uuid,
166
+ chargeStartDateTime: csv.ChargeStartDateTime,
167
+ name: csv.Name,
168
+ vin: csv.Vin,
169
+ model: csv.Model,
170
+ country: csv.Country,
171
+ siteLocationName: csv.SiteLocationName,
172
+ description: csv.Description,
173
+ ucom: csv.QuantityBase.unit,
174
+ quantityBase: csv.QuantityBase.value,
175
+ quantityTier1: csv.QuantityTier1?.value,
176
+ quantityTier2: csv.QuantityTier2?.value,
177
+ quantityTier3: csv.QuantityTier3?.value,
178
+ quantityTier4: csv.QuantityTier4?.value,
179
+ invoiceNumber: csv.InvoiceNumber,
180
+ unitCostBase: csv.UnitCostBase.value,
181
+ unitCostTier1: csv.UnitCostTier1?.value,
182
+ unitCostTier2: csv.UnitCostTier2?.value,
183
+ unitCostTier3: csv.UnitCostTier3?.value,
184
+ unitCostTier4: csv.UnitCostTier4?.value,
185
+ vat: castNum("VAT", csv.VAT),
186
+ totalExcVat: castNum("Total Exc. VAT", csv["Total Exc. VAT"]),
187
+ totalIncVat: castNum("Total Inc. VAT", csv["Total Inc. VAT"]),
188
+ status: csv.Status,
189
+ invoice: csv.Invoice,
190
+ };
191
+ return removeUndefined(result);
192
+ };
193
+ //# sourceMappingURL=invoicesCsv.common.js.map