@etainabl/nodejs-sdk 1.3.181 → 1.3.184

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/esm/index.js CHANGED
@@ -3270,7 +3270,7 @@ var require_lodash = __commonJS({
3270
3270
  result2.__values__ = wrapper.__values__;
3271
3271
  return result2;
3272
3272
  }
3273
- function chunk2(array, size2, guard) {
3273
+ function chunk3(array, size2, guard) {
3274
3274
  if (guard ? isIterateeCall(array, size2, guard) : size2 === undefined2) {
3275
3275
  size2 = 1;
3276
3276
  } else {
@@ -5142,7 +5142,7 @@ var require_lodash = __commonJS({
5142
5142
  lodash.bindKey = bindKey;
5143
5143
  lodash.castArray = castArray;
5144
5144
  lodash.chain = chain2;
5145
- lodash.chunk = chunk2;
5145
+ lodash.chunk = chunk3;
5146
5146
  lodash.compact = compact;
5147
5147
  lodash.concat = concat;
5148
5148
  lodash.cond = cond;
@@ -5870,19 +5870,6 @@ var api_default = (auth, instanceOptions = {}) => {
5870
5870
  removeAccount: factory.remove(etainablApi, "accounts"),
5871
5871
  getAccountSchema: factory.get(etainablApi, "accounts", "schema"),
5872
5872
  invalidateAccountCache: factory.customWithId(etainablApi, "put", "accounts", "invalidate-cache"),
5873
- // alert triggers
5874
- getAlertTrigger: factory.getWithId(etainablApi, "alert-triggers"),
5875
- listAlertTriggers: factory.list(etainablApi, "alert-triggers"),
5876
- updateAlertTrigger: factory.update(etainablApi, "alert-triggers"),
5877
- createAlertTrigger: factory.create(etainablApi, "alert-triggers"),
5878
- removeAlertTrigger: factory.remove(etainablApi, "alert-triggers"),
5879
- bulkUpdateAlertTriggers: factory.create(
5880
- etainablApi,
5881
- "alert-triggers",
5882
- "bulk-update"
5883
- ),
5884
- retryAlertTrigger: factory.customWithId(etainablApi, "post", "alert-triggers", "retry"),
5885
- cancelAlertTrigger: factory.customWithId(etainablApi, "post", "alert-triggers", "cancel"),
5886
5873
  // custom alert triggers
5887
5874
  getCustomAlertTrigger: factory.getWithId(etainablApi, "custom-alert-triggers"),
5888
5875
  listCustomAlertTriggers: factory.list(etainablApi, "custom-alert-triggers"),
@@ -6281,28 +6268,28 @@ var emailTemplate_default = (options) => {
6281
6268
  import mjml2html from "mjml";
6282
6269
  var severityConfig = {
6283
6270
  error: {
6284
- color: "#DC2626",
6285
- bgColor: "#FEE2E2",
6271
+ color: "#FFFFFF",
6272
+ bgColor: "#e04f1a",
6286
6273
  label: "ERROR"
6287
6274
  },
6288
6275
  success: {
6289
- color: "#EA580C",
6290
- bgColor: "#23ae2aff",
6276
+ color: "#FFFFFF",
6277
+ bgColor: "#82b54b",
6291
6278
  label: "SUCCESS"
6292
6279
  },
6293
6280
  warning: {
6294
- color: "#F59E0B",
6295
- bgColor: "#FEF3C7",
6281
+ color: "#FFFFFF",
6282
+ bgColor: "#ff9f43",
6296
6283
  label: "WARNING"
6297
6284
  },
6298
6285
  tip: {
6299
- color: "#3B82F6",
6300
- bgColor: "#DBEAFE",
6286
+ color: "#FFFFFF",
6287
+ bgColor: "#00bad1",
6301
6288
  label: "TIP"
6302
6289
  },
6303
6290
  info: {
6304
- color: "#5ECFB1",
6305
- bgColor: "#D1FAE5",
6291
+ color: "#FFFFFF",
6292
+ bgColor: "#5ECFB1",
6306
6293
  label: "INFO"
6307
6294
  }
6308
6295
  };
@@ -6310,13 +6297,17 @@ function generateNotificationEmail(options) {
6310
6297
  if (!process.env.ETAINABL_UI_URL) {
6311
6298
  throw new Error("ETAINABL_UI_URL environment variable is not set");
6312
6299
  }
6313
- const { title, message, severity = "info", category = "Notification", actions = [], metadata = {} } = options;
6300
+ const { title, message, severity = "info", category = "Notification", actions = [], metadata = {}, items = [] } = options;
6314
6301
  const config = severityConfig[severity];
6302
+ const isSingleItem = items.length === 1;
6303
+ const hasMultipleItems = items.length > 1;
6304
+ const mainTitle = isSingleItem && items[0]?.message ? items[0].message : message;
6305
+ const subtitle = isSingleItem ? message : title;
6315
6306
  const mjmlTemplate = `
6316
6307
  <mjml>
6317
6308
  <mj-head>
6318
- <mj-title>${message} - Etainabl</mj-title>
6319
- <mj-preview>${title}</mj-preview>
6309
+ <mj-title>${mainTitle}</mj-title>
6310
+ <mj-preview>${subtitle}</mj-preview>
6320
6311
 
6321
6312
  <mj-attributes>
6322
6313
  <mj-all font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica', 'Arial', sans-serif" />
@@ -6327,9 +6318,9 @@ function generateNotificationEmail(options) {
6327
6318
  <mj-style inline="inline">
6328
6319
  .severity-badge {
6329
6320
  display: inline-block;
6330
- padding: 4px 12px;
6331
- border-radius: 12px;
6332
- font-size: 11px;
6321
+ padding: 2px 6px;
6322
+ border-radius: 6px;
6323
+ font-size: 9px;
6333
6324
  font-weight: 600;
6334
6325
  letter-spacing: 0.5px;
6335
6326
  background-color: ${config.bgColor};
@@ -6371,7 +6362,7 @@ function generateNotificationEmail(options) {
6371
6362
  </mj-section>
6372
6363
 
6373
6364
  <!-- Spacer -->
6374
- <mj-section background-color="#F3F4F6" padding="20px 0">
6365
+ <mj-section background-color="#F3F4F6" padding="6px 0">
6375
6366
  <mj-column>
6376
6367
  <mj-text></mj-text>
6377
6368
  </mj-column>
@@ -6394,23 +6385,60 @@ function generateNotificationEmail(options) {
6394
6385
  </mj-column>
6395
6386
  </mj-section>
6396
6387
 
6397
- <!-- Message (Main Title) -->
6388
+ <!-- Main Title -->
6398
6389
  <mj-section padding="0 32px 8px 32px">
6399
6390
  <mj-column>
6400
6391
  <mj-text font-size="24px" font-weight="600" color="#1F2937" line-height="1.3" padding="0">
6401
- ${message}
6392
+ ${mainTitle}
6402
6393
  </mj-text>
6403
6394
  </mj-column>
6404
6395
  </mj-section>
6405
6396
 
6406
- <!-- Title (Subtitle) -->
6397
+ <!-- Subtitle -->
6407
6398
  <mj-section padding="0 32px 24px 32px">
6408
6399
  <mj-column>
6409
6400
  <mj-text font-size="14px" color="#6B7280" padding="0">
6410
- ${title}
6401
+ ${subtitle}
6402
+ </mj-text>
6403
+ </mj-column>
6404
+ </mj-section>
6405
+
6406
+ ${hasMultipleItems ? (() => {
6407
+ const maxItems = 3;
6408
+ const displayItems = items.slice(0, maxItems);
6409
+ const remainingCount = items.length - maxItems;
6410
+ return `
6411
+ <!-- Items List -->
6412
+ <mj-section padding="0 32px 24px 32px">
6413
+ <mj-column>
6414
+ <mj-text padding="0">
6415
+ <table style="width: 100%; border-collapse: collapse;">
6416
+ ${displayItems.map(
6417
+ (item) => `
6418
+ <tr>
6419
+ <td style="padding: 0 0 8px 0;">
6420
+ <table style="width: 100%; border-collapse: collapse; background-color: #F9FAFB; border-radius: 6px; overflow: hidden;">
6421
+ <tr>
6422
+ <td style="width: 6px; background-color: #5ECFB1; border-radius: 10px;"></td>
6423
+ <td style="padding: 16px;">
6424
+ <span style="color: #1F2937; font-size: 14px; line-height: 1.5;">${item.message}</span>
6425
+ </td>
6426
+ </tr>
6427
+ </table>
6428
+ </td>
6429
+ </tr>`
6430
+ ).join("")}${remainingCount > 0 ? `
6431
+ <tr>
6432
+ <td style="padding: 8px 0 0 0;">
6433
+ <span style="color: #6B7280; font-size: 13px; font-style: italic;">and ${remainingCount} more item${remainingCount === 1 ? "" : "s"}...</span>
6434
+ </td>
6435
+ </tr>` : ""}
6436
+ </table>
6411
6437
  </mj-text>
6412
6438
  </mj-column>
6413
6439
  </mj-section>
6440
+ `;
6441
+ })() : ""}
6414
6442
 
6415
6443
  ${Object.keys(metadata).length > 0 ? `
6416
6444
  <!-- Metadata Section -->
@@ -6463,7 +6491,7 @@ function generateNotificationEmail(options) {
6463
6491
  <mj-section padding="0 32px 24px 32px">
6464
6492
  <mj-column>
6465
6493
  <mj-button
6466
- background-color="#1F2937"
6494
+ background-color="#65c198"
6467
6495
  color="#FFFFFF"
6468
6496
  border-radius="6px"
6469
6497
  font-weight="600"
@@ -6508,7 +6536,7 @@ function generateNotificationEmail(options) {
6508
6536
  <a href="${process.env.ETAINABL_UI_URL}/messages/notifications" style="color: #5ECFB1; text-decoration: none;">Manage notification preferences</a>
6509
6537
  </mj-text>
6510
6538
  <mj-text align="center" font-size="11px" color="#9CA3AF" padding-top="16px">
6511
- \xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} Etainabl. All rights reserved.
6539
+ \xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} Etainabl Ltd. All rights reserved.
6512
6540
  </mj-text>
6513
6541
  </mj-column>
6514
6542
  </mj-section>
@@ -6626,10 +6654,10 @@ var ChecksumStream = class extends Duplex {
6626
6654
  }
6627
6655
  _read(size) {
6628
6656
  }
6629
- _write(chunk2, encoding, callback) {
6657
+ _write(chunk3, encoding, callback) {
6630
6658
  try {
6631
- this.checksum.update(chunk2);
6632
- this.push(chunk2);
6659
+ this.checksum.update(chunk3);
6660
+ this.push(chunk3);
6633
6661
  } catch (e4) {
6634
6662
  return callback(e4);
6635
6663
  }
@@ -6668,9 +6696,9 @@ var createChecksumStream = ({ expectedChecksum, checksum, source, checksumSource
6668
6696
  const transform = new TransformStream({
6669
6697
  start() {
6670
6698
  },
6671
- async transform(chunk2, controller) {
6672
- checksum.update(chunk2);
6673
- controller.enqueue(chunk2);
6699
+ async transform(chunk3, controller) {
6700
+ checksum.update(chunk3);
6701
+ controller.enqueue(chunk3);
6674
6702
  },
6675
6703
  async flush(controller) {
6676
6704
  const digest = await checksum.digest();
@@ -6743,7 +6771,7 @@ function createBufferedReadableStream(upstream, size, logger) {
6743
6771
  let mode = -1;
6744
6772
  const pull = async (controller) => {
6745
6773
  const { value, done } = await reader.read();
6746
- const chunk2 = value;
6774
+ const chunk3 = value;
6747
6775
  if (done) {
6748
6776
  if (mode !== -1) {
6749
6777
  const remainder = flush(buffers, mode);
@@ -6753,7 +6781,7 @@ function createBufferedReadableStream(upstream, size, logger) {
6753
6781
  }
6754
6782
  controller.close();
6755
6783
  } else {
6756
- const chunkMode = modeOf(chunk2, false);
6784
+ const chunkMode = modeOf(chunk3, false);
6757
6785
  if (mode !== chunkMode) {
6758
6786
  if (mode >= 0) {
6759
6787
  controller.enqueue(flush(buffers, mode));
@@ -6761,16 +6789,16 @@ function createBufferedReadableStream(upstream, size, logger) {
6761
6789
  mode = chunkMode;
6762
6790
  }
6763
6791
  if (mode === -1) {
6764
- controller.enqueue(chunk2);
6792
+ controller.enqueue(chunk3);
6765
6793
  return;
6766
6794
  }
6767
- const chunkSize = sizeOf(chunk2);
6795
+ const chunkSize = sizeOf(chunk3);
6768
6796
  bytesSeen += chunkSize;
6769
6797
  const bufferSize = sizeOf(buffers[mode]);
6770
6798
  if (chunkSize >= size && bufferSize === 0) {
6771
- controller.enqueue(chunk2);
6799
+ controller.enqueue(chunk3);
6772
6800
  } else {
6773
- const newSize = merge(buffers, mode, chunk2);
6801
+ const newSize = merge(buffers, mode, chunk3);
6774
6802
  if (!streamBufferingLoggedWarning && bytesSeen > size * 2) {
6775
6803
  streamBufferingLoggedWarning = true;
6776
6804
  logger?.warn(`@smithy/util-stream - stream chunk size ${chunkSize} is below threshold of ${size}, automatically buffering.`);
@@ -6787,14 +6815,14 @@ function createBufferedReadableStream(upstream, size, logger) {
6787
6815
  pull
6788
6816
  });
6789
6817
  }
6790
- function merge(buffers, mode, chunk2) {
6818
+ function merge(buffers, mode, chunk3) {
6791
6819
  switch (mode) {
6792
6820
  case 0:
6793
- buffers[0] += chunk2;
6821
+ buffers[0] += chunk3;
6794
6822
  return sizeOf(buffers[0]);
6795
6823
  case 1:
6796
6824
  case 2:
6797
- buffers[mode].push(chunk2);
6825
+ buffers[mode].push(chunk3);
6798
6826
  return sizeOf(buffers[mode]);
6799
6827
  }
6800
6828
  }
@@ -6810,17 +6838,17 @@ function flush(buffers, mode) {
6810
6838
  }
6811
6839
  throw new Error(`@smithy/util-stream - invalid index ${mode} given to flush()`);
6812
6840
  }
6813
- function sizeOf(chunk2) {
6814
- return chunk2?.byteLength ?? chunk2?.length ?? 0;
6841
+ function sizeOf(chunk3) {
6842
+ return chunk3?.byteLength ?? chunk3?.length ?? 0;
6815
6843
  }
6816
- function modeOf(chunk2, allowBuffer = true) {
6817
- if (allowBuffer && typeof Buffer !== "undefined" && chunk2 instanceof Buffer) {
6844
+ function modeOf(chunk3, allowBuffer = true) {
6845
+ if (allowBuffer && typeof Buffer !== "undefined" && chunk3 instanceof Buffer) {
6818
6846
  return 2;
6819
6847
  }
6820
- if (chunk2 instanceof Uint8Array) {
6848
+ if (chunk3 instanceof Uint8Array) {
6821
6849
  return 1;
6822
6850
  }
6823
- if (typeof chunk2 === "string") {
6851
+ if (typeof chunk3 === "string") {
6824
6852
  return 0;
6825
6853
  }
6826
6854
  return -1;
@@ -6841,8 +6869,8 @@ function createBufferedReadable(upstream, size, logger) {
6841
6869
  new ByteArrayCollector((size2) => Buffer.from(new Uint8Array(size2)))
6842
6870
  ];
6843
6871
  let mode = -1;
6844
- upstream.on("data", (chunk2) => {
6845
- const chunkMode = modeOf(chunk2, true);
6872
+ upstream.on("data", (chunk3) => {
6873
+ const chunkMode = modeOf(chunk3, true);
6846
6874
  if (mode !== chunkMode) {
6847
6875
  if (mode >= 0) {
6848
6876
  downstream.push(flush(buffers, mode));
@@ -6850,16 +6878,16 @@ function createBufferedReadable(upstream, size, logger) {
6850
6878
  mode = chunkMode;
6851
6879
  }
6852
6880
  if (mode === -1) {
6853
- downstream.push(chunk2);
6881
+ downstream.push(chunk3);
6854
6882
  return;
6855
6883
  }
6856
- const chunkSize = sizeOf(chunk2);
6884
+ const chunkSize = sizeOf(chunk3);
6857
6885
  bytesSeen += chunkSize;
6858
6886
  const bufferSize = sizeOf(buffers[mode]);
6859
6887
  if (chunkSize >= size && bufferSize === 0) {
6860
- downstream.push(chunk2);
6888
+ downstream.push(chunk3);
6861
6889
  } else {
6862
- const newSize = merge(buffers, mode, chunk2);
6890
+ const newSize = merge(buffers, mode, chunk3);
6863
6891
  if (!streamBufferingLoggedWarning && bytesSeen > size * 2) {
6864
6892
  streamBufferingLoggedWarning = true;
6865
6893
  logger?.warn(`@smithy/util-stream - stream chunk size ${chunkSize} is below threshold of ${size}, automatically buffering.`);
@@ -6934,14 +6962,14 @@ async function headStream(stream, bytes) {
6934
6962
  reader.releaseLock();
6935
6963
  const collected = new Uint8Array(Math.min(bytes, byteLengthCounter));
6936
6964
  let offset = 0;
6937
- for (const chunk2 of chunks) {
6938
- if (chunk2.byteLength > collected.byteLength - offset) {
6939
- collected.set(chunk2.subarray(0, collected.byteLength - offset), offset);
6965
+ for (const chunk3 of chunks) {
6966
+ if (chunk3.byteLength > collected.byteLength - offset) {
6967
+ collected.set(chunk3.subarray(0, collected.byteLength - offset), offset);
6940
6968
  break;
6941
6969
  } else {
6942
- collected.set(chunk2, offset);
6970
+ collected.set(chunk3, offset);
6943
6971
  }
6944
- offset += chunk2.length;
6972
+ offset += chunk3.length;
6945
6973
  }
6946
6974
  return collected;
6947
6975
  }
@@ -6970,9 +6998,9 @@ var Collector = class extends Writable {
6970
6998
  buffers = [];
6971
6999
  limit = Infinity;
6972
7000
  bytesBuffered = 0;
6973
- _write(chunk2, encoding, callback) {
6974
- this.buffers.push(chunk2);
6975
- this.bytesBuffered += chunk2.byteLength ?? 0;
7001
+ _write(chunk3, encoding, callback) {
7002
+ this.buffers.push(chunk3);
7003
+ this.bytesBuffered += chunk3.byteLength ?? 0;
6976
7004
  if (this.bytesBuffered >= this.limit) {
6977
7005
  const excess = this.bytesBuffered - this.limit;
6978
7006
  const tailBuffer = this.buffers[this.buffers.length - 1];
@@ -8570,9 +8598,7 @@ async function sendNotificationMessageBatch({
8570
8598
  const results = await Bluebird.mapSeries(chunks, async (batch) => {
8571
8599
  const entries = batch.map((msg, index) => ({
8572
8600
  Id: `msg-${index}`,
8573
- MessageBody: JSON.stringify(
8574
- createNotificationMessage(msg.eventName, msg.context, msg.input)
8575
- )
8601
+ MessageBody: JSON.stringify(createNotificationMessage(msg.eventName, msg.context, msg.input))
8576
8602
  }));
8577
8603
  const command = new SendMessageBatchCommand({
8578
8604
  QueueUrl: queueUrl,
@@ -8874,7 +8900,10 @@ __export(utils_exports, {
8874
8900
  automationSources: () => automationSources,
8875
8901
  getMeterPointNumberBottomLine: () => getMeterPointNumberBottomLine,
8876
8902
  isTransientError: () => isTransientError,
8903
+ paginatedFetch: () => paginatedFetch,
8904
+ sendToSqsBatched: () => sendToSqsBatched,
8877
8905
  units: () => units,
8906
+ updateBatchJobStatus: () => updateBatchJobStatus,
8878
8907
  utilityTypes: () => utilityTypes,
8879
8908
  wasteCategories: () => wasteCategories
8880
8909
  });
@@ -9181,6 +9210,63 @@ var getMeterPointNumberBottomLine = (meterPointNumber) => {
9181
9210
  return "";
9182
9211
  };
9183
9212
 
9213
+ // src/utils/job.ts
9214
+ async function updateBatchJobStatus({
9215
+ etnApi,
9216
+ automationRun,
9217
+ accountKey,
9218
+ status,
9219
+ errorMessage
9220
+ }) {
9221
+ if (!automationRun) return;
9222
+ const jobKey = automationRun.jobId;
9223
+ const resolvedAccountKey = accountKey ?? automationRun.accountResults?.[0]?.id?.toString();
9224
+ if (!jobKey || !resolvedAccountKey) return;
9225
+ let jobEntry;
9226
+ try {
9227
+ jobEntry = await etnApi.getJob(jobKey);
9228
+ } catch (error) {
9229
+ console.error("Failed to fetch job for status update", {
9230
+ jobKey,
9231
+ accountKey: resolvedAccountKey,
9232
+ error
9233
+ });
9234
+ return;
9235
+ }
9236
+ if (!jobEntry || jobEntry.status === "completed" || jobEntry.status === "failed") return;
9237
+ const metadata = jobEntry.metadata ?? {};
9238
+ const completedAccountKeys = new Set(metadata.completedAccountKeys ?? []);
9239
+ const failedAccountKeys = new Set(metadata.failedAccountKeys ?? []);
9240
+ const { accountCount } = metadata;
9241
+ const now = (/* @__PURE__ */ new Date()).toISOString();
9242
+ if (status === "failed") {
9243
+ failedAccountKeys.add(resolvedAccountKey);
9244
+ } else {
9245
+ completedAccountKeys.add(resolvedAccountKey);
9246
+ }
9247
+ const updatePayload = {
9248
+ metadata: {
9249
+ ...metadata,
9250
+ completedAccountKeys: Array.from(completedAccountKeys),
9251
+ failedAccountKeys: Array.from(failedAccountKeys),
9252
+ completedCount: completedAccountKeys.size,
9253
+ failedCount: failedAccountKeys.size
9254
+ }
9255
+ };
9256
+ const totalProcessed = completedAccountKeys.size + failedAccountKeys.size;
9257
+ const hasFailures = failedAccountKeys.size > 0;
9258
+ if (status === "failed") {
9259
+ updatePayload.metadata = { ...updatePayload.metadata, result: "failed" };
9260
+ updatePayload.error = errorMessage || "Automation run failed";
9261
+ }
9262
+ if (accountCount && totalProcessed >= accountCount) {
9263
+ updatePayload.status = "completed";
9264
+ updatePayload.completedAt = now;
9265
+ updatePayload.metadata = { ...updatePayload.metadata, result: hasFailures ? "failed" : "success" };
9266
+ }
9267
+ await etnApi.updateJob(jobEntry._id, updatePayload);
9268
+ }
9269
+
9184
9270
  // node_modules/@aws-sdk/middleware-expect-continue/dist-es/index.js
9185
9271
  function addExpectContinueMiddleware(options) {
9186
9272
  return (next) => async (args) => {
@@ -12472,9 +12558,9 @@ var HeaderMarshaller = class {
12472
12558
  }
12473
12559
  const out = new Uint8Array(chunks.reduce((carry, bytes) => carry + bytes.byteLength, 0));
12474
12560
  let position = 0;
12475
- for (const chunk2 of chunks) {
12476
- out.set(chunk2, position);
12477
- position += chunk2.byteLength;
12561
+ for (const chunk3 of chunks) {
12562
+ out.set(chunk3, position);
12563
+ position += chunk3.byteLength;
12478
12564
  }
12479
12565
  return out;
12480
12566
  }
@@ -12794,8 +12880,8 @@ var SmithyMessageEncoderStream = class {
12794
12880
  return this.asyncIterator();
12795
12881
  }
12796
12882
  async *asyncIterator() {
12797
- for await (const chunk2 of this.options.inputStream) {
12798
- const payloadBuf = this.options.serializer(chunk2);
12883
+ for await (const chunk3 of this.options.inputStream) {
12884
+ const payloadBuf = this.options.serializer(chunk3);
12799
12885
  yield payloadBuf;
12800
12886
  }
12801
12887
  }
@@ -12979,9 +13065,9 @@ var HashCalculator = class extends Writable2 {
12979
13065
  super(options);
12980
13066
  this.hash = hash;
12981
13067
  }
12982
- _write(chunk2, encoding, callback) {
13068
+ _write(chunk3, encoding, callback) {
12983
13069
  try {
12984
- this.hash.update(toUint8Array(chunk2));
13070
+ this.hash.update(toUint8Array(chunk3));
12985
13071
  } catch (err) {
12986
13072
  return callback(err);
12987
13073
  }
@@ -13576,6 +13662,54 @@ function isTransientError(error) {
13576
13662
  return false;
13577
13663
  }
13578
13664
 
13665
+ // src/utils/pagination.ts
13666
+ var paginatedFetch = async (fetchPage, options = {}) => {
13667
+ const { pageSize = 100 } = options;
13668
+ const fetchAllPages = async (skip, accumulated) => {
13669
+ const response = await fetchPage({ $limit: pageSize, $skip: skip });
13670
+ accumulated.push(...response.data);
13671
+ return response.data.length < pageSize ? accumulated : fetchAllPages(skip + pageSize, accumulated);
13672
+ };
13673
+ return fetchAllPages(0, []);
13674
+ };
13675
+
13676
+ // src/utils/sqs.ts
13677
+ var import_lodash2 = __toESM(require_lodash(), 1);
13678
+ import Bluebird2 from "bluebird";
13679
+ var sendToSqsBatched = async (messages, options) => {
13680
+ const { queueUrl, concurrency = 5, batchSize = 10 } = options;
13681
+ const sqsClient = options.sqsClient ?? new SQSClient({ region: "eu-west-1" });
13682
+ if (messages.length === 0) {
13683
+ return { successful: 0, failed: 0 };
13684
+ }
13685
+ const batches = (0, import_lodash2.chunk)(messages, batchSize);
13686
+ let successful = 0;
13687
+ let failed = 0;
13688
+ await Bluebird2.map(
13689
+ batches,
13690
+ async (batch, batchIndex) => {
13691
+ const entries = batch.map((message, index) => ({
13692
+ Id: message.id ?? `msg_${batchIndex}_${index}`,
13693
+ MessageBody: JSON.stringify(message.body),
13694
+ ...message.attributes && { MessageAttributes: message.attributes }
13695
+ }));
13696
+ const response = await sqsClient.send(
13697
+ new SendMessageBatchCommand({
13698
+ QueueUrl: queueUrl,
13699
+ Entries: entries
13700
+ })
13701
+ );
13702
+ successful += response.Successful?.length ?? 0;
13703
+ if (response.Failed && response.Failed.length > 0) {
13704
+ failed += response.Failed.length;
13705
+ throw new Error(`Failed to send ${response.Failed.length} SQS messages in batch ${batchIndex}`);
13706
+ }
13707
+ },
13708
+ { concurrency }
13709
+ );
13710
+ return { successful, failed };
13711
+ };
13712
+
13579
13713
  // src/openai/index.ts
13580
13714
  var openai_exports = {};
13581
13715
  __export(openai_exports, {
@@ -15678,7 +15812,16 @@ var errorCodeMap = {
15678
15812
  unique: true
15679
15813
  }
15680
15814
  };
15681
- var dataFetchersIds = ["bacnet", "solis", "solarman", "gridfetch", "smartflow", "smartvatten", "beringar", "4dmonitoring"];
15815
+ var dataFetchersIds = [
15816
+ "bacnet",
15817
+ "solis",
15818
+ "solarman",
15819
+ "gridfetch",
15820
+ "smartflow",
15821
+ "smartvatten",
15822
+ "beringar",
15823
+ "4dmonitoring"
15824
+ ];
15682
15825
  function sendEmail(lambdaSource, context, error, destinations) {
15683
15826
  const sesClient = new SESClient({ region: "eu-west-1" });
15684
15827
  const template = emailTemplate_default({
@@ -15807,6 +15950,15 @@ async function handleError({ context, etnApi, automationRun, error, lambdaSource
15807
15950
  if (automationRun.category === "account" && accountId) {
15808
15951
  await etnApi.updateAccountStatusForAutomation(automation._id, accountId, { status: "error", error: error.message });
15809
15952
  }
15953
+ if (automation.category === "account") {
15954
+ await updateBatchJobStatus({
15955
+ etnApi,
15956
+ automationRun,
15957
+ accountKey: accountId,
15958
+ status: "failed",
15959
+ errorMessage: error.message
15960
+ });
15961
+ }
15810
15962
  }
15811
15963
  async function deleteMessage(queueUrl, receiptHandle, sqsClient) {
15812
15964
  if (!queueUrl || !receiptHandle) {
@@ -15845,27 +15997,18 @@ var NotificationDefaultChannels = {
15845
15997
  };
15846
15998
 
15847
15999
  // src/types/notificationTemplate.ts
15848
- var NotificationTemplateCategories = [
15849
- "automation",
15850
- "report",
15851
- "team",
15852
- "dataQuality",
15853
- "discussion",
15854
- "scraper"
15855
- ];
15856
16000
  var EventNamesByCategory = {
15857
- automation: ["automationFailed", "runCompleted", "hasnotRun", "fileNotExpected"],
16001
+ automation: ["automationFailed", "automationCompleted", "automationOverdue", "automationExtractorOverdue"],
15858
16002
  report: ["reportSuccess", "reportFailed"],
15859
16003
  team: ["newUserSignIn"],
15860
- dataQuality: ["thresholdBreached", "approachingThreshold", "readingOverdue", "readingDueSoon", "contractRenewalUpcoming", "contractRenewalOverdue"],
15861
- discussion: ["commentAdded", "mentionInComment"],
15862
- scraper: ["scraperLoginError", "scraperHasnotRun", "scraperRunCompleted"]
16004
+ dataQuality: ["invoiceOverdue", "contractOverdue", "contractDueSoon", "readingOverdue", "readingDueSoon"],
16005
+ discussion: ["newDiscussionReply", "userAssignedToDiscussion", "discussionMessageDue"],
16006
+ scraper: ["scraperLoginError", "scraperHasNotRun", "scraperRunCompleted"]
15863
16007
  };
15864
16008
  export {
15865
16009
  EventNamesByCategory,
15866
16010
  NotificationCategoryList,
15867
16011
  NotificationDefaultChannels,
15868
- NotificationTemplateCategories,
15869
16012
  ObjectId,
15870
16013
  api_default as api,
15871
16014
  consumption_exports as consumption,