@open-charging-cloud/chargy-core 0.11.3 → 0.12.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.
@@ -5,6 +5,7 @@ import { ed448ph, ed448 } from '@noble/curves/ed448.js';
5
5
  import { p521, p384, p256 } from '@noble/curves/nist.js';
6
6
  import { secp256k1 } from '@noble/curves/secp256k1.js';
7
7
  import { ml_dsa87, ml_dsa65, ml_dsa44 } from '@noble/post-quantum/ml-dsa.js';
8
+ import { sha256 as sha256$1 } from '@noble/hashes/sha2.js';
8
9
  import { Buffer as Buffer$1 } from 'buffer';
9
10
  import { fileTypeFromBuffer } from 'file-type';
10
11
  import isURL from 'is-url-superb';
@@ -54,7 +55,7 @@ var IECCurves = /* @__PURE__ */ ((IECCurves2) => {
54
55
  IECCurves2["secp256k1"] = "secp256k1";
55
56
  IECCurves2["secp256r1"] = "secp256r1";
56
57
  IECCurves2["secp384r1"] = "secp384r1";
57
- IECCurves2["secp512r1"] = "secp512r1";
58
+ IECCurves2["secp521r1"] = "secp521r1";
58
59
  return IECCurves2;
59
60
  })(IECCurves || {});
60
61
  var IEncoding = /* @__PURE__ */ ((IEncoding2) => {
@@ -515,12 +516,45 @@ function SetHex(dv, hex, offset, reverse) {
515
516
  }
516
517
  return buf2hex(buffer);
517
518
  }
519
+ var meterTimeZone = "Europe/Berlin";
520
+ var statesItsOwnUTCOffset = /[+-]\d{2}:?\d{2}$/;
521
+ function timeZoneOffsetMinutes(instant, timeZone = meterTimeZone) {
522
+ const parts = new Intl.DateTimeFormat("en-US", {
523
+ timeZone,
524
+ hour12: false,
525
+ year: "numeric",
526
+ month: "2-digit",
527
+ day: "2-digit",
528
+ hour: "2-digit",
529
+ minute: "2-digit",
530
+ second: "2-digit"
531
+ }).formatToParts(instant);
532
+ const field = (type) => Number(parts.find((part) => part.type === type)?.value ?? "0");
533
+ const asUTC = Date.UTC(
534
+ field("year"),
535
+ field("month") - 1,
536
+ field("day"),
537
+ field("hour") % 24,
538
+ // Intl may report midnight as hour 24
539
+ field("minute"),
540
+ field("second")
541
+ );
542
+ return (asUTC - Math.floor(instant.getTime() / 1e3) * 1e3) / 6e4;
543
+ }
544
+ function meterLocalTime(timestamp) {
545
+ if (typeof timestamp !== "string")
546
+ return { moment: timestamp, offsetMinutes: timestamp.utcOffset() };
547
+ const parsed = moment.parseZone(timestamp);
548
+ return {
549
+ moment: parsed,
550
+ offsetMinutes: statesItsOwnUTCOffset.test(timestamp.trim()) ? parsed.utcOffset() : timeZoneOffsetMinutes(new Date(parsed.valueOf()))
551
+ };
552
+ }
518
553
  function SetTimestamp(dv, timestamp, offset, addLocalOffset = true) {
519
554
  if (timestamp == void 0)
520
555
  throw new Error("Timestamp is missing!");
521
- if (typeof timestamp === "string")
522
- timestamp = parseUTC(timestamp);
523
- const unixtime = timestamp.unix() + (addLocalOffset ? 60 * timestamp.utcOffset() : 0);
556
+ const meterTime = meterLocalTime(timestamp);
557
+ const unixtime = meterTime.moment.unix() + (addLocalOffset ? 60 * meterTime.offsetMinutes : 0);
524
558
  const bytes = getInt64Bytes(unixtime);
525
559
  const buffer = new ArrayBuffer(8);
526
560
  const tv = new DataView(buffer);
@@ -533,9 +567,8 @@ function SetTimestamp(dv, timestamp, offset, addLocalOffset = true) {
533
567
  function SetTimestamp32(dv, timestamp, offset, addLocalOffset = true) {
534
568
  if (timestamp == void 0)
535
569
  throw new Error("Timestamp is missing!");
536
- if (typeof timestamp === "string")
537
- timestamp = parseUTC(timestamp);
538
- const unixtime = timestamp.unix() + (addLocalOffset ? 60 * timestamp.utcOffset() : 0);
570
+ const meterTime = meterLocalTime(timestamp);
571
+ const unixtime = meterTime.moment.unix() + (addLocalOffset ? 60 * meterTime.offsetMinutes : 0);
539
572
  const bytes = getInt64Bytes(unixtime);
540
573
  const buffer = new ArrayBuffer(4);
541
574
  const tv = new DataView(buffer);
@@ -945,7 +978,10 @@ var secp224k1 = class {
945
978
  N = BigInt("0x010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7");
946
979
  // Number of points in the field
947
980
  Acurve = BigInt(0);
948
- // Defined on the elliptic curve. y^2 = x^3 + Acurve * x + 5
981
+ // Defined on the elliptic curve. y^2 = x^3 + Acurve * x + Bcurve
982
+ Bcurve = BigInt(5);
983
+ // secp224k1 has a = 0 and b = 5, and a cofactor of 1, so every
984
+ // point on the curve except infinity has order N.
949
985
  Gx = BigInt("0xA1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C");
950
986
  Gy = BigInt("0x7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
951
987
  GPoint = [this.Gx, this.Gy];
@@ -959,16 +995,42 @@ var secp224k1 = class {
959
995
  }
960
996
  return null;
961
997
  }
998
+ // Returns true only for a signature that verifies against a public key which
999
+ // is a valid point on the curve. Every other outcome is false, including a
1000
+ // point off the curve and any failure while computing, so that a caller
1001
+ // trying several candidate keys is never interrupted by an exception.
962
1002
  validate(hash, signatureR, signatureS, PublicKey) {
963
- if (signatureR == this.Zero || signatureR >= this.N)
1003
+ if (signatureR <= this.Zero || signatureR >= this.N)
964
1004
  throw new Error("Invalid R");
965
- if (signatureS == this.Zero || signatureS >= this.N)
1005
+ if (signatureS <= this.Zero || signatureS >= this.N)
966
1006
  throw new Error("Invalid S");
967
- const w = this.modInv(signatureS, this.N);
968
- const u1 = this.ECmultiply(this.GPoint, this.modulo(w * hash, this.N));
969
- const u2 = this.ECmultiply(PublicKey, this.modulo(w * signatureR, this.N));
970
- const validation = this.ECadd(u1, u2);
971
- return validation[0] == signatureR;
1007
+ if (!this.isOnCurve(PublicKey))
1008
+ return false;
1009
+ try {
1010
+ const w = this.modInv(signatureS, this.N);
1011
+ const u1 = this.ECmultiply(this.GPoint, this.modulo(w * hash, this.N));
1012
+ const u2 = this.ECmultiply(PublicKey, this.modulo(w * signatureR, this.N));
1013
+ const validation = this.ECadd(u1, u2);
1014
+ const x = validation[0];
1015
+ if (x === void 0)
1016
+ return false;
1017
+ return this.modulo(x, this.N) === signatureR;
1018
+ } catch {
1019
+ return false;
1020
+ }
1021
+ }
1022
+ // y^2 == x^3 + Acurve * x + Bcurve (mod Pcurve), with both coordinates
1023
+ // reduced. The point at infinity has no [x, y] representation here and is
1024
+ // therefore rejected along with everything else that is malformed.
1025
+ isOnCurve(point) {
1026
+ const x = point[0];
1027
+ const y = point[1];
1028
+ if (x === void 0 || y === void 0)
1029
+ return false;
1030
+ if (x < this.Zero || x >= this.Pcurve || y < this.Zero || y >= this.Pcurve) {
1031
+ return false;
1032
+ }
1033
+ return this.modulo(y * y, this.Pcurve) === this.modulo(x * x * x + this.Acurve * x + this.Bcurve, this.Pcurve);
972
1034
  }
973
1035
  modulo(n, m) {
974
1036
  return (n % m + m) % m;
@@ -981,6 +1043,8 @@ var secp224k1 = class {
981
1043
  }
982
1044
  modInv(a, n = this.Pcurve) {
983
1045
  let lm = BigInt(1), hm = BigInt(0), high = n, low = this.modulo(a, n);
1046
+ if (low === this.Zero)
1047
+ throw new Error("Value is not invertible!");
984
1048
  while (low > 1) {
985
1049
  const ratio = high / low, nm = hm - ratio * lm, newm = high - ratio * low;
986
1050
  hm = lm;
@@ -992,6 +1056,12 @@ var secp224k1 = class {
992
1056
  }
993
1057
  ECadd(a, b) {
994
1058
  if (a[0] != void 0 && b[0] != void 0 && a[1] != void 0 && b[1] != void 0) {
1059
+ if (this.modulo(a[0] - b[0], this.Pcurve) === this.Zero) {
1060
+ if (this.modulo(a[1] - b[1], this.Pcurve) === this.Zero && this.modulo(a[1], this.Pcurve) !== this.Zero) {
1061
+ return this.ECdouble(a);
1062
+ }
1063
+ throw new Error("EC point addition results in the point at infinity!");
1064
+ }
995
1065
  const LamAdd = this.modulo((b[1] - a[1]) * this.modInv(b[0] - a[0]), this.Pcurve);
996
1066
  const x = this.modulo(LamAdd * LamAdd - a[0] - b[0], this.Pcurve);
997
1067
  const y = this.modulo(LamAdd * (a[0] - x) - a[1], this.Pcurve);
@@ -4032,6 +4102,7 @@ async function signJSONMessage(JSONMessage, KeyPairs, options) {
4032
4102
  return false;
4033
4103
  if (JSONMessage.signatures != null && !Array.isArray(JSONMessage.signatures))
4034
4104
  return false;
4105
+ let signaturesCreated = 0;
4035
4106
  for (const KeyPair of KeyPairs) {
4036
4107
  if (KeyPair == null || !isNobleSignatureKeyPair(KeyPair))
4037
4108
  continue;
@@ -4063,8 +4134,6 @@ async function signJSONMessage(JSONMessage, KeyPairs, options) {
4063
4134
  signatureJSON.context = bytesToBase64(options.context);
4064
4135
  signatureJSON.contextHEX = bytesToHex(options.context);
4065
4136
  }
4066
- JSONMessage.signatures ??= [];
4067
- JSONMessage.signatures.push(signatureJSON);
4068
4137
  const signatureIsValid = suite.verify(
4069
4138
  plainText,
4070
4139
  signatureBytes,
@@ -4073,8 +4142,11 @@ async function signJSONMessage(JSONMessage, KeyPairs, options) {
4073
4142
  );
4074
4143
  if (!signatureIsValid)
4075
4144
  return false;
4145
+ JSONMessage.signatures ??= [];
4146
+ JSONMessage.signatures.push(signatureJSON);
4147
+ signaturesCreated++;
4076
4148
  }
4077
- return true;
4149
+ return signaturesCreated > 0;
4078
4150
  }
4079
4151
  async function verifyJSONSignature(JSONMessage, signature, options) {
4080
4152
  return isVerificationTrue(await verifyJSONSignatureResult(JSONMessage, signature, options));
@@ -5892,8 +5964,20 @@ var OCMF = class {
5892
5964
  message: this.chargy.GetMultilanguageText("Each OCMF data set must have at least one meter reading!"),
5893
5965
  certainty: 0
5894
5966
  };
5967
+ const sessionId = "OCMF-" + bytesToHex(
5968
+ sha256$1(
5969
+ new TextEncoder().encode(
5970
+ OCMFJSONDocuments.map(
5971
+ (ocmfJSONDocument) => canonicalJSONStringify({
5972
+ payload: ocmfJSONDocument.payload,
5973
+ signature: ocmfJSONDocument.signature
5974
+ })
5975
+ ).join("\n")
5976
+ )
5977
+ )
5978
+ );
5895
5979
  const CTR = {
5896
- "@id": "?",
5980
+ "@id": sessionId,
5897
5981
  "@context": "https://open.charging.cloud/contexts/CTR+json",
5898
5982
  //"@context": [ "https://open.charging.cloud/contexts/CTR+json", "https://open.charging.cloud/contexts/CTR_OCMF+json" ],
5899
5983
  "begin": "?",
@@ -5983,7 +6067,7 @@ var OCMF = class {
5983
6067
  // }]
5984
6068
  // }],
5985
6069
  "chargingSessions": [{
5986
- "@id": "1554181214441:-1965658344385548683:2",
6070
+ "@id": sessionId,
5987
6071
  "@context": "https://open.charging.cloud/contexts/SessionSignatureFormats/OCMFv1.0+json",
5988
6072
  "begin": "?",
5989
6073
  "end": "?",
@@ -6029,8 +6113,26 @@ var OCMF = class {
6029
6113
  if (containerEVSE !== void 0 && CTR.chargingSessions?.[0] !== void 0) {
6030
6114
  const chargingSession = CTR.chargingSessions[0];
6031
6115
  chargingSession.EVSEId ??= containerEVSE["@id"];
6032
- if (chargingSession.EVSEId === containerEVSE["@id"])
6033
- chargingSession.EVSE = containerEVSE;
6116
+ if (chargingSession.EVSEId === containerEVSE["@id"]) {
6117
+ const containerEnergyMeter = containerEVSE.energyMeters?.[0];
6118
+ const resolvedEnergyMeter = containerEnergyMeter !== void 0 || meterSerial !== void 0 ? {
6119
+ ...containerEnergyMeter,
6120
+ "@id": meterSerial ?? containerEnergyMeter?.["@id"] ?? "",
6121
+ manufacturer: {
6122
+ ...containerEnergyMeter?.manufacturer,
6123
+ name: meterVendor ?? containerEnergyMeter?.manufacturer?.name
6124
+ },
6125
+ model: {
6126
+ ...containerEnergyMeter?.model,
6127
+ name: meterModel ?? containerEnergyMeter?.model?.name
6128
+ },
6129
+ firmware: {
6130
+ ...containerEnergyMeter?.firmware,
6131
+ version: meterFirmware ?? containerEnergyMeter?.firmware?.version
6132
+ }
6133
+ } : void 0;
6134
+ chargingSession.EVSE = resolvedEnergyMeter !== void 0 ? { ...containerEVSE, energyMeters: [resolvedEnergyMeter] } : containerEVSE;
6135
+ }
6034
6136
  }
6035
6137
  const resolvedConnectorId = signedConnectorId ?? containerConnector?.["@id"];
6036
6138
  if ((resolvedConnectorId !== void 0 || signedCable !== void 0) && CTR.chargingSessions?.[0] !== void 0) {
@@ -6189,8 +6291,16 @@ var OCMF = class {
6189
6291
  CTR.warnings = (CTR.warnings ?? []).concat(ContainerInfos.warnings);
6190
6292
  CTR.status = OCMFJSONDocuments.every((ocmfJSONDocument) => ocmfJSONDocument.validationStatus === "ValidSignature" /* ValidSignature */) ? "ValidSignature" /* ValidSignature */ : "InvalidSignature" /* InvalidSignature */;
6191
6293
  if (CTR.chargingSessions != null && CTR.chargingSessions.length > 0 && CTR.chargingSessions[0]) {
6192
- CTR.begin = CTR.chargingSessions[0].begin;
6193
- CTR.end = CTR.chargingSessions[0].end;
6294
+ const firstChargingSession = CTR.chargingSessions[0];
6295
+ const measurementTimestamps = firstChargingSession.measurements.flatMap((measurement) => measurement.values).map((value) => value.timestamp).filter((timestamp) => isMandatoryString(timestamp) && !Number.isNaN(Date.parse(timestamp))).sort((left, right) => Date.parse(left) - Date.parse(right));
6296
+ const firstTimestamp = measurementTimestamps[0];
6297
+ const lastTimestamp = measurementTimestamps[measurementTimestamps.length - 1];
6298
+ if (firstTimestamp !== void 0 && lastTimestamp !== void 0) {
6299
+ firstChargingSession.begin = firstTimestamp;
6300
+ firstChargingSession.end = lastTimestamp;
6301
+ }
6302
+ CTR.begin = firstChargingSession.begin;
6303
+ CTR.end = firstChargingSession.end;
6194
6304
  return CTR;
6195
6305
  }
6196
6306
  }
@@ -6854,8 +6964,29 @@ var OCPI = class {
6854
6964
  const address = asJSONObject(placeInfo?.["address"]);
6855
6965
  const geoLat = asNumber(geoLocation?.["lat"]);
6856
6966
  const geoLon = asNumber(geoLocation?.["lon"]);
6967
+ const meterInfo = asJSONObject(SomeJSON["meterInfo"]);
6968
+ const containerEnergyMeter = meterInfo !== void 0 ? {
6969
+ "@id": asString(meterInfo["meterId"]) ?? "",
6970
+ manufacturer: {
6971
+ name: asString(meterInfo["manufacturer"]),
6972
+ url: asString(meterInfo["manufacturerURL"])
6973
+ },
6974
+ model: {
6975
+ name: asString(meterInfo["model"]),
6976
+ url: asString(meterInfo["modelURL"])
6977
+ },
6978
+ hardware: {
6979
+ revision: asString(meterInfo["hardwareVersion"])
6980
+ },
6981
+ firmware: {
6982
+ version: asString(meterInfo["firmwareVersion"])
6983
+ }
6984
+ } : void 0;
6857
6985
  const containerInfos = {
6858
- EVSEIds: [evseId],
6986
+ EVSEs: evseId !== void 0 ? [{
6987
+ "@id": evseId,
6988
+ energyMeters: containerEnergyMeter !== void 0 ? [containerEnergyMeter] : void 0
6989
+ }] : void 0,
6859
6990
  chargingStations: [{
6860
6991
  "@id": evseIdStr.substring(0, evseIdStr.lastIndexOf("*")),
6861
6992
  geoLocation: geoLat !== void 0 && geoLon !== void 0 ? { lat: geoLat, lng: geoLon } : void 0,
@@ -6866,7 +6997,6 @@ var OCPI = class {
6866
6997
  country: asString(address["country"]) ?? ""
6867
6998
  } : void 0
6868
6999
  }]
6869
- //energyMeter: chargyLib.asJSONObject(SomeJSON["meterInfo"])
6870
7000
  };
6871
7001
  return new OCMF(this.chargy).TryToParseOCMFDocument(
6872
7002
  firstSignedData,
@@ -9810,7 +9940,7 @@ var ChargePointCrypt01 = class extends ACrypt {
9810
9940
  if (plainText !== "" && chargingSession.signature != null && chargingSession.signature !== "") {
9811
9941
  let sha225Value = null;
9812
9942
  let sha256Value = null;
9813
- let sha385Value = null;
9943
+ let sha384Value = null;
9814
9944
  let sha512Value = null;
9815
9945
  for (const publicKey of publicKeys) {
9816
9946
  const algorithm = typeof publicKey.algorithm === "object" ? publicKey.algorithm.name : publicKey.algorithm;
@@ -9835,9 +9965,9 @@ var ChargePointCrypt01 = class extends ACrypt {
9835
9965
  ) ? "ValidSignature" /* ValidSignature */ : "InvalidSignature" /* InvalidSignature */;
9836
9966
  break;
9837
9967
  case "secp384r1":
9838
- sha385Value = sha385Value ?? await sha384(plainText);
9968
+ sha384Value = sha384Value ?? await sha384(plainText);
9839
9969
  sessionResult = this.curve384r1.keyFromPublic(publicKey.value, "hex").verify(
9840
- sha385Value,
9970
+ sha384Value,
9841
9971
  chargingSession.signature
9842
9972
  ) ? "ValidSignature" /* ValidSignature */ : "InvalidSignature" /* InvalidSignature */;
9843
9973
  break;
@@ -9859,12 +9989,13 @@ var ChargePointCrypt01 = class extends ACrypt {
9859
9989
  chargingSession.hashValue = sha256Value ?? "";
9860
9990
  break;
9861
9991
  case "secp384r1":
9862
- chargingSession.hashValue = sha385Value ?? "";
9992
+ chargingSession.hashValue = sha384Value ?? "";
9863
9993
  break;
9864
9994
  case "secp521r1":
9865
9995
  chargingSession.hashValue = sha512Value ?? "";
9866
9996
  break;
9867
9997
  }
9998
+ break;
9868
9999
  }
9869
10000
  }
9870
10001
  }
@@ -9986,7 +10117,7 @@ var ChargePointCrypt01 = class extends ACrypt {
9986
10117
  case "secp384r1":
9987
10118
  hashInfo = "(SHA384, 384 Bits, hex)";
9988
10119
  break;
9989
- case "secp512r1":
10120
+ case "secp521r1":
9990
10121
  hashInfo = "(SHA512, 512 Bits, hex)";
9991
10122
  break;
9992
10123
  }
@@ -10376,8 +10507,14 @@ var validationRules_default = {
10376
10507
  function isPdfAttachment(value) {
10377
10508
  if (!isMandatoryJSONObject(value))
10378
10509
  return false;
10379
- return typeof value["filename"] === "string" && (value["content"] instanceof ArrayBuffer || ArrayBuffer.isView(value["content"]));
10510
+ return typeof value["filename"] === "string";
10380
10511
  }
10512
+ var pdfAttachmentTypes = [
10513
+ { extension: ".chargy", type: "application/chargy", info: "A CHARGY file extracted from a PDF/A-3 or newer attachment" },
10514
+ { extension: ".xml", type: "application/xml", info: "A XML file extracted from a PDF/A-3 or newer attachment" },
10515
+ { extension: ".json", type: "application/json", info: "A JSON file extracted from a PDF/A-3 or newer attachment" },
10516
+ { extension: ".csv", type: "text/csv", info: "A CSV file extracted from a PDF/A-3 or newer attachment" }
10517
+ ];
10381
10518
  var Chargy = class {
10382
10519
  //#region Data
10383
10520
  i18n;
@@ -10476,7 +10613,9 @@ var Chargy = class {
10476
10613
  case "1.3.101.113":
10477
10614
  KeyType = "EdDSA";
10478
10615
  break;
10616
+ case "2.16.840.1.101.3.4.3.17":
10479
10617
  case "2.16.840.1.101.3.4.3.18":
10618
+ case "2.16.840.1.101.3.4.3.19":
10480
10619
  KeyType = "ML-DSA";
10481
10620
  break;
10482
10621
  }
@@ -10489,9 +10628,15 @@ var Chargy = class {
10489
10628
  case "1.3.101.113":
10490
10629
  Algorithm = "Ed448";
10491
10630
  break;
10631
+ case "2.16.840.1.101.3.4.3.17":
10632
+ Algorithm = "ML-DSA-44";
10633
+ break;
10492
10634
  case "2.16.840.1.101.3.4.3.18":
10493
10635
  Algorithm = "ML-DSA-65";
10494
10636
  break;
10637
+ case "2.16.840.1.101.3.4.3.19":
10638
+ Algorithm = "ML-DSA-87";
10639
+ break;
10495
10640
  // Koblitz 224-bit curve
10496
10641
  case "1.3.132.0.32":
10497
10642
  Algorithm = "secp224k1";
@@ -10510,7 +10655,7 @@ var Chargy = class {
10510
10655
  break;
10511
10656
  }
10512
10657
  const publicKeyData = new Uint8Array(publicKeyDER.publicKey.data);
10513
- const expectedLength = Algorithm === "Ed25519" ? 32 : Algorithm === "Ed448" ? 57 : Algorithm === "ML-DSA-65" ? 1952 : void 0;
10658
+ const expectedLength = Algorithm === "Ed25519" ? 32 : Algorithm === "Ed448" ? 57 : Algorithm === "ML-DSA-44" ? 1312 : Algorithm === "ML-DSA-65" ? 1952 : Algorithm === "ML-DSA-87" ? 2592 : void 0;
10514
10659
  if (publicKeyDER.publicKey.unused !== void 0 && publicKeyDER.publicKey.unused !== 0)
10515
10660
  throw new Error("The SubjectPublicKeyInfo public key has unused bits!");
10516
10661
  if (expectedLength !== void 0 && publicKeyData.length !== expectedLength)
@@ -10557,7 +10702,7 @@ var Chargy = class {
10557
10702
  publicKeyDER
10558
10703
  ).publicKeys[0];
10559
10704
  const algorithm = typeof publicKey?.algorithm === "string" ? publicKey.algorithm : publicKey?.algorithm.name;
10560
- return algorithm === "Ed25519" || algorithm === "Ed448" || algorithm === "ML-DSA-65" ? publicKey?.value : buf2hex(publicKeyDER);
10705
+ return algorithm === "Ed25519" || algorithm === "Ed448" || algorithm?.startsWith("ML-DSA-") === true ? publicKey?.value : buf2hex(publicKeyDER);
10561
10706
  } catch {
10562
10707
  return void 0;
10563
10708
  }
@@ -10570,7 +10715,7 @@ var Chargy = class {
10570
10715
  publicKeyDER
10571
10716
  ).publicKeys[0];
10572
10717
  const algorithm = typeof publicKey?.algorithm === "string" ? publicKey.algorithm : publicKey?.algorithm.name;
10573
- return algorithm === "Ed25519" || algorithm === "Ed448" || algorithm === "ML-DSA-65" ? publicKey?.value : buf2hex(publicKeyDER);
10718
+ return algorithm === "Ed25519" || algorithm === "Ed448" || algorithm?.startsWith("ML-DSA-") === true ? publicKey?.value : buf2hex(publicKeyDER);
10574
10719
  } catch {
10575
10720
  return void 0;
10576
10721
  }
@@ -11146,45 +11291,27 @@ var Chargy = class {
11146
11291
  const pdfDocument = fileInfo.data ? await pdfjsLib.getDocument({ data: fileInfo.data }).promise : fileInfo.path != null && fileInfo.path.length > 0 ? await pdfjsLib.getDocument({ url: fileInfo.path }).promise : null;
11147
11292
  if (pdfDocument !== null) {
11148
11293
  try {
11149
- const attachmentsUnknown = await pdfDocument.getAttachments();
11150
- if (isMandatoryJSONObject(attachmentsUnknown))
11151
- Object.values(attachmentsUnknown).forEach((attachmentUnknown) => {
11152
- if (!isPdfAttachment(attachmentUnknown))
11153
- return;
11154
- const attachment = attachmentUnknown;
11155
- if (attachment.filename.endsWith(".chargy"))
11156
- expandedFiles.push({
11157
- name: attachment.filename,
11158
- path: FileInfos[0]?.path,
11159
- type: "application/chargy",
11160
- data: attachment.content,
11161
- info: "A CHARGY file extracted from a PDF/A-3 or newer attachment"
11162
- });
11163
- else if (attachment.filename.endsWith(".xml"))
11164
- expandedFiles.push({
11165
- name: attachment.filename,
11166
- path: FileInfos[0]?.path,
11167
- type: "application/xml",
11168
- data: attachment.content,
11169
- info: "A XML file extracted from a PDF/A-3 or newer attachment"
11170
- });
11171
- else if (attachment.filename.endsWith(".json"))
11172
- expandedFiles.push({
11173
- name: attachment.filename,
11174
- path: FileInfos[0]?.path,
11175
- type: "application/json",
11176
- data: attachment.content,
11177
- info: "A JSON file extracted from a PDF/A-3 or newer attachment"
11178
- });
11179
- else if (attachment.filename.endsWith(".csv"))
11180
- expandedFiles.push({
11181
- name: attachment.filename,
11182
- path: FileInfos[0]?.path,
11183
- type: "text/csv",
11184
- data: attachment.content,
11185
- info: "A CSV file extracted from a PDF/A-3 or newer attachment"
11186
- });
11294
+ const attachments = await pdfDocument.getAttachments();
11295
+ for (const [attachmentId, attachmentUnknown] of attachments ?? []) {
11296
+ if (!isPdfAttachment(attachmentUnknown))
11297
+ continue;
11298
+ const attachment = attachmentUnknown;
11299
+ const attachmentType = pdfAttachmentTypes.find(
11300
+ (candidate) => attachment.filename.endsWith(candidate.extension)
11301
+ );
11302
+ if (attachmentType === void 0)
11303
+ continue;
11304
+ const content = attachment.content ?? await pdfDocument.getAttachmentContent(attachmentId);
11305
+ if (content == null)
11306
+ continue;
11307
+ expandedFiles.push({
11308
+ name: attachment.filename,
11309
+ path: FileInfos[0]?.path,
11310
+ type: attachmentType.type,
11311
+ data: content,
11312
+ info: attachmentType.info
11187
11313
  });
11314
+ }
11188
11315
  } catch (error) {
11189
11316
  console.error(`Error extracting PDF/A-3 attachments: ${String(error)}`);
11190
11317
  }
@@ -11782,6 +11909,6 @@ var Chargy = class {
11782
11909
  }
11783
11910
  };
11784
11911
 
11785
- export { ACrypt, Alfen, AlfenCrypt01, BSMCrypt01, CanonicalJSONError, ChargeIT, ChargePoint, ChargePointCrypt01, IChargeTransparencyLiveLink_exports as ChargeTransparencyLiveLink, ChargeTransparencyLiveLinkContext, IChargeTransparencyRecord_exports as ChargeTransparencyRecord, Chargy, chargyInterfaces_exports as ChargyInterfaces, Clone, CloneCTR, ConcatenateBuffers, CreateDiv, CreateDiv2, CreateError, CreateWarning, CryptoAlgorithms, CryptoHashAlgorithms, DayOfWeek, DisplayPrefixes, EDL40, EDL40Crypt01, EDL40ValidationError, EDL40_OBIS, EDL40_SESSION_CONTEXT, EDL40_SIGNATURE_CONTEXT, EMHCrypt01, ErrorLevel, GDFCrypt01, IECCurves, IEncoding, InformationRelevance, InformationRelevanceToString, IsAChargeTransparencyLiveLink, IsAChargeTransparencyRecord, IsAPublicKey, IsAPublicKeyLookup, IsAPublicKeySignature, IsAPublicKeyXY, IsASessionCryptoResult, IsAURL, IsNullOrEmpty, IsValidURL, JSONSignatureVerificationStatus, MENNEKES_EDL40_OBIS, MENNEKES_EDL40_XMLNS, Mennekes, MennekesCrypt01, OBIS2Hex, OBIS2MeasurementName, OBIS_RegExpr, OCMF, OCMFBonnTariffParseError, OCMFTransactionTypes, OCMF_SIGNATURE_ALGORITHMS, OCMFv1_x, OCPI, OIDInfo, PCDF, PCDFCrypt01, PCDFParseError, PCDFValidationError, PCDF_FIELD_ORDER, PCDF_PREFIX, PTB, ParseJSON_LD, PublicKeyFormats, IPublicKeyInfo_exports as PublicKeyInfo, SAFEXML, SessionVerificationResult, SetHex, SetInt8, SetText, SetText_withLength, SetTimestamp, SetTimestamp32, SetUInt32, SetUInt32_withCode, SetUInt64, SetUInt64D, SignMessage, SignatureFormats, IURL_exports as SimpleURL, TimeStatusTypes, URLContext, UTC2human, VerificationResult, VerifyJSONMessageSignatures, WarningLevel, WhenNullOrEmpty, XMLContainer, asJSONArray, asJSONObject, asNumber, asString, base64ToBytes, buf2hex, buildEDL40Signature, buildIsaSignature, buildMennekesSignatureData, bytesToBase64, bytesToHex, canParseEDL40, canonicalJSONBytes, canonicalJSONStringify, cleanHex, closeFullscreen, createCompatibleCurve, createHexString, createLegacyP192Curve, dateToMennekesLocalEpochSeconds, decodeSmlMessages, extractMennekesChargingProcesses, findEntryByObis, findGetListRes, firstKey, firstValue, generateSignatureKeyPair, getArrayElement, getArrayLikeElement, getDirectChildByLocalName, getDirectChildrenByLocalName, getElementsByLocalName, getFirstArrayElement, getInt16Bytes, getInt32Bytes, getInt64Bytes, getInt8Bytes, getLastArrayElement, getOCMFSignatureDisplay, getSignatureSuite, getTrimmedTextContent, hashFile, hex2bin, hex32, hexToArrayBuffer, hexToBytes, intFromBytes, isEncodedValue, isGeoLocation, isI18NString, isICryptoResult, isIFileInfo, isISessionCryptoResult1, isISessionCryptoResult2, isJSONLDObject, isMandatoryArrayOfStrings, isMandatoryBoolean, isMandatoryDecimal, isMandatoryJSONArray, isMandatoryJSONObject, isMandatoryNumber, isMandatoryString, isMandatoryURL, isOIDInfo, isObject, isOptionalArrayOfStrings, isOptionalDecimal, isOptionalJSONArray, isOptionalJSONArrayError, isOptionalJSONArrayOk, isOptionalJSONObject, isOptionalNumber, isOptionalString, isOptionalStringArray, isOptionalStringOrOIDInfo, isOptionalURL, isPCDFText, isPublicKeySubject, isString, isStringArray, isStringOrOIDInfo, isStringOrStringArray, isaListNameContext, jsonPrettyPrinter, measurementName2human, normalizePCDFPublicKeyHex, normalizeXMLText, ocmfBonnTariffToChargingTariff, openFullscreen, pad, parseAndVerifyJSONSignatures, parseDescription, parseEDL40, parseHexString, parseMennekesXMLDocument, parseNumber, parseOBIS, parseOCMFBonnTariffText, parsePCDFDocument, parsePCDFPublicKey, parsePCDFSignature, parseSmlTime, parseUTC, readQRCodeTextFromImage, readQRCodeTextFromImageData, readTLV, secp224k1, setUILocale, sha256, sha256____, sha384, sha384____, sha512, sha512____, signJSONMessage, signMessage, stripPCDFControlCharacters, stripTransport, time2human, toArrayBuffer, toSessionVerificationResults, toUint8Array, transformEDL40Status, tryParseOCMFBonnTariffText, unquotePCDFText, validatePCDFFields, verifyEDL40Document, verifyJSONMessageSignatureResults, verifyJSONMessageSignatures, verifyJSONSignature, verifyJSONSignatureResult, verifyPCDFDocument };
11912
+ export { ACrypt, Alfen, AlfenCrypt01, BSMCrypt01, CanonicalJSONError, ChargeIT, ChargePoint, ChargePointCrypt01, IChargeTransparencyLiveLink_exports as ChargeTransparencyLiveLink, ChargeTransparencyLiveLinkContext, IChargeTransparencyRecord_exports as ChargeTransparencyRecord, Chargy, chargyInterfaces_exports as ChargyInterfaces, Clone, CloneCTR, ConcatenateBuffers, CreateDiv, CreateDiv2, CreateError, CreateWarning, CryptoAlgorithms, CryptoHashAlgorithms, DayOfWeek, DisplayPrefixes, EDL40, EDL40Crypt01, EDL40ValidationError, EDL40_OBIS, EDL40_SESSION_CONTEXT, EDL40_SIGNATURE_CONTEXT, EMHCrypt01, ErrorLevel, GDFCrypt01, IECCurves, IEncoding, InformationRelevance, InformationRelevanceToString, IsAChargeTransparencyLiveLink, IsAChargeTransparencyRecord, IsAPublicKey, IsAPublicKeyLookup, IsAPublicKeySignature, IsAPublicKeyXY, IsASessionCryptoResult, IsAURL, IsNullOrEmpty, IsValidURL, JSONSignatureVerificationStatus, MENNEKES_EDL40_OBIS, MENNEKES_EDL40_XMLNS, Mennekes, MennekesCrypt01, OBIS2Hex, OBIS2MeasurementName, OBIS_RegExpr, OCMF, OCMFBonnTariffParseError, OCMFTransactionTypes, OCMF_SIGNATURE_ALGORITHMS, OCMFv1_x, OCPI, OIDInfo, PCDF, PCDFCrypt01, PCDFParseError, PCDFValidationError, PCDF_FIELD_ORDER, PCDF_PREFIX, PTB, ParseJSON_LD, PublicKeyFormats, IPublicKeyInfo_exports as PublicKeyInfo, SAFEXML, SessionVerificationResult, SetHex, SetInt8, SetText, SetText_withLength, SetTimestamp, SetTimestamp32, SetUInt32, SetUInt32_withCode, SetUInt64, SetUInt64D, SignMessage, SignatureFormats, IURL_exports as SimpleURL, TimeStatusTypes, URLContext, UTC2human, VerificationResult, VerifyJSONMessageSignatures, WarningLevel, WhenNullOrEmpty, XMLContainer, asJSONArray, asJSONObject, asNumber, asString, base64ToBytes, buf2hex, buildEDL40Signature, buildIsaSignature, buildMennekesSignatureData, bytesToBase64, bytesToHex, canParseEDL40, canonicalJSONBytes, canonicalJSONStringify, cleanHex, closeFullscreen, createCompatibleCurve, createHexString, createLegacyP192Curve, dateToMennekesLocalEpochSeconds, decodeSmlMessages, extractMennekesChargingProcesses, findEntryByObis, findGetListRes, firstKey, firstValue, generateSignatureKeyPair, getArrayElement, getArrayLikeElement, getDirectChildByLocalName, getDirectChildrenByLocalName, getElementsByLocalName, getFirstArrayElement, getInt16Bytes, getInt32Bytes, getInt64Bytes, getInt8Bytes, getLastArrayElement, getOCMFSignatureDisplay, getSignatureSuite, getTrimmedTextContent, hashFile, hex2bin, hex32, hexToArrayBuffer, hexToBytes, intFromBytes, isEncodedValue, isGeoLocation, isI18NString, isICryptoResult, isIFileInfo, isISessionCryptoResult1, isISessionCryptoResult2, isJSONLDObject, isMandatoryArrayOfStrings, isMandatoryBoolean, isMandatoryDecimal, isMandatoryJSONArray, isMandatoryJSONObject, isMandatoryNumber, isMandatoryString, isMandatoryURL, isOIDInfo, isObject, isOptionalArrayOfStrings, isOptionalDecimal, isOptionalJSONArray, isOptionalJSONArrayError, isOptionalJSONArrayOk, isOptionalJSONObject, isOptionalNumber, isOptionalString, isOptionalStringArray, isOptionalStringOrOIDInfo, isOptionalURL, isPCDFText, isPublicKeySubject, isString, isStringArray, isStringOrOIDInfo, isStringOrStringArray, isaListNameContext, jsonPrettyPrinter, measurementName2human, meterTimeZone, normalizePCDFPublicKeyHex, normalizeXMLText, ocmfBonnTariffToChargingTariff, openFullscreen, pad, parseAndVerifyJSONSignatures, parseDescription, parseEDL40, parseHexString, parseMennekesXMLDocument, parseNumber, parseOBIS, parseOCMFBonnTariffText, parsePCDFDocument, parsePCDFPublicKey, parsePCDFSignature, parseSmlTime, parseUTC, readQRCodeTextFromImage, readQRCodeTextFromImageData, readTLV, secp224k1, setUILocale, sha256, sha256____, sha384, sha384____, sha512, sha512____, signJSONMessage, signMessage, stripPCDFControlCharacters, stripTransport, time2human, timeZoneOffsetMinutes, toArrayBuffer, toSessionVerificationResults, toUint8Array, transformEDL40Status, tryParseOCMFBonnTariffText, unquotePCDFText, validatePCDFFields, verifyEDL40Document, verifyJSONMessageSignatureResults, verifyJSONMessageSignatures, verifyJSONSignature, verifyJSONSignatureResult, verifyPCDFDocument };
11786
11913
  //# sourceMappingURL=index.js.map
11787
11914
  //# sourceMappingURL=index.js.map