@loadstrike/loadstrike-sdk 1.0.22801 → 1.0.23001

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.
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.__loadstrikeTestExports = exports.EndpointAdapterFactory = exports.KafkaSaslOptions = exports.HttpAuthOptions = exports.HttpOAuth2ClientCredentialsOptions = exports.PushDiffusionEndpointDefinition = exports.DelegateStreamEndpointDefinition = exports.AzureEventHubsEndpointDefinition = exports.RedisStreamsEndpointDefinition = exports.NatsEndpointDefinition = exports.RabbitMqEndpointDefinition = exports.KafkaEndpointDefinition = exports.HttpEndpointDefinition = exports.TrafficEndpointDefinition = exports.LOADSTRIKE_TRACE_ID_TRACKING_FIELD = exports.LOADSTRIKE_TRACE_ID_HEADER = void 0;
36
+ exports.__loadstrikeTestExports = exports.EndpointAdapterFactory = exports.KafkaSaslOptions = exports.HttpAuthOptions = exports.HttpOAuth2ClientCredentialsOptions = exports.PushDiffusionEndpointDefinition = exports.DelegateStreamEndpointDefinition = exports.SqsEndpointDefinition = exports.AzureEventHubsEndpointDefinition = exports.RedisStreamsEndpointDefinition = exports.NatsEndpointDefinition = exports.RabbitMqEndpointDefinition = exports.KafkaEndpointDefinition = exports.HttpEndpointDefinition = exports.TrafficEndpointDefinition = exports.LOADSTRIKE_TRACE_ID_TRACKING_FIELD = exports.LOADSTRIKE_TRACE_ID_HEADER = void 0;
37
37
  const node_crypto_1 = require("node:crypto");
38
38
  const correlation_js_1 = require("./correlation.js");
39
39
  exports.LOADSTRIKE_TRACE_ID_HEADER = "loadstrike-trace-id";
@@ -254,6 +254,35 @@ class AzureEventHubsEndpointDefinitionModel extends TrafficEndpointDefinitionMod
254
254
  }
255
255
  }
256
256
  }
257
+ class SqsEndpointDefinitionModel extends TrafficEndpointDefinitionModel {
258
+ constructor(initial) {
259
+ super(initial);
260
+ this.Kind = "Sqs";
261
+ this.QueueUrl = "";
262
+ this.Region = "";
263
+ this.WaitTimeSeconds = 1;
264
+ this.MaxNumberOfMessages = 1;
265
+ this.DeleteAfterConsume = true;
266
+ initializeSqsEndpointDefinitionModel(this, initial);
267
+ }
268
+ Validate() {
269
+ super.Validate();
270
+ requireNonEmptyString(this.QueueUrl, "QueueUrl must be provided for AWS SQS endpoint.");
271
+ requireNonEmptyString(this.Region, "Region must be provided for AWS SQS endpoint.");
272
+ if (String(this.AccessKeyId ?? "").trim() && !String(this.SecretAccessKey ?? "").trim()) {
273
+ throw new Error("SecretAccessKey must be provided when AccessKeyId is configured for AWS SQS endpoint.");
274
+ }
275
+ if (this.WaitTimeSeconds < 0 || this.WaitTimeSeconds > 20) {
276
+ throw new RangeError("WaitTimeSeconds must be between 0 and 20 for AWS SQS endpoint.");
277
+ }
278
+ if (this.MaxNumberOfMessages <= 0 || this.MaxNumberOfMessages > 10) {
279
+ throw new RangeError("MaxNumberOfMessages must be between 1 and 10 for AWS SQS endpoint.");
280
+ }
281
+ if (this.VisibilityTimeoutSeconds != null && this.VisibilityTimeoutSeconds < 0) {
282
+ throw new RangeError("VisibilityTimeoutSeconds must be zero or greater when configured.");
283
+ }
284
+ }
285
+ }
257
286
  class DelegateStreamEndpointDefinitionModel extends TrafficEndpointDefinitionModel {
258
287
  constructor(initial) {
259
288
  super(initial);
@@ -299,6 +328,7 @@ exports.RabbitMqEndpointDefinition = RabbitMqEndpointDefinitionModel;
299
328
  exports.NatsEndpointDefinition = NatsEndpointDefinitionModel;
300
329
  exports.RedisStreamsEndpointDefinition = RedisStreamsEndpointDefinitionModel;
301
330
  exports.AzureEventHubsEndpointDefinition = AzureEventHubsEndpointDefinitionModel;
331
+ exports.SqsEndpointDefinition = SqsEndpointDefinitionModel;
302
332
  exports.DelegateStreamEndpointDefinition = DelegateStreamEndpointDefinitionModel;
303
333
  exports.PushDiffusionEndpointDefinition = PushDiffusionEndpointDefinitionModel;
304
334
  exports.HttpOAuth2ClientCredentialsOptions = HttpOAuth2ClientCredentialsOptionsModel;
@@ -662,6 +692,44 @@ function initializeAzureEventHubsEndpointDefinitionModel(target, initial) {
662
692
  target.PartitionCount = pickOptionalEndpointNumber(raw, "PartitionCount", "partitionCount");
663
693
  }
664
694
  }
695
+ function initializeSqsEndpointDefinitionModel(target, initial) {
696
+ const raw = asRecordOrEmpty(initial);
697
+ const queueUrl = pickOptionalEndpointString(raw, "QueueUrl", "queueUrl");
698
+ if (queueUrl) {
699
+ target.QueueUrl = queueUrl;
700
+ }
701
+ const region = pickOptionalEndpointString(raw, "Region", "region");
702
+ if (region) {
703
+ target.Region = region;
704
+ }
705
+ if (hasAnyEndpointField(raw, ["ServiceUrl", "serviceUrl"])) {
706
+ target.ServiceUrl = pickOptionalEndpointString(raw, "ServiceUrl", "serviceUrl");
707
+ }
708
+ if (hasAnyEndpointField(raw, ["AccessKeyId", "accessKeyId"])) {
709
+ target.AccessKeyId = pickOptionalEndpointString(raw, "AccessKeyId", "accessKeyId");
710
+ }
711
+ if (hasAnyEndpointField(raw, ["SecretAccessKey", "secretAccessKey"])) {
712
+ target.SecretAccessKey = pickOptionalEndpointStringAllowEmpty(raw, "SecretAccessKey", "secretAccessKey");
713
+ }
714
+ if (hasAnyEndpointField(raw, ["SessionToken", "sessionToken"])) {
715
+ target.SessionToken = pickOptionalEndpointString(raw, "SessionToken", "sessionToken");
716
+ }
717
+ const waitTimeSeconds = pickOptionalEndpointNumber(raw, "WaitTimeSeconds", "waitTimeSeconds");
718
+ if (waitTimeSeconds != null) {
719
+ target.WaitTimeSeconds = waitTimeSeconds;
720
+ }
721
+ const maxNumberOfMessages = pickOptionalEndpointNumber(raw, "MaxNumberOfMessages", "maxNumberOfMessages");
722
+ if (maxNumberOfMessages != null) {
723
+ target.MaxNumberOfMessages = maxNumberOfMessages;
724
+ }
725
+ if (hasAnyEndpointField(raw, ["VisibilityTimeoutSeconds", "visibilityTimeoutSeconds"])) {
726
+ target.VisibilityTimeoutSeconds = pickOptionalEndpointNumber(raw, "VisibilityTimeoutSeconds", "visibilityTimeoutSeconds");
727
+ }
728
+ const deleteAfterConsume = pickEndpointBoolean(raw, "DeleteAfterConsume", "deleteAfterConsume");
729
+ if (deleteAfterConsume != null) {
730
+ target.DeleteAfterConsume = deleteAfterConsume;
731
+ }
732
+ }
665
733
  function initializeDelegateStreamEndpointDefinitionModel(target, initial) {
666
734
  const raw = asRecordOrEmpty(initial);
667
735
  const produce = pickEndpointFunction(raw, "Produce", "produce");
@@ -798,6 +866,7 @@ const protocolBus = new class InMemoryProtocolBus {
798
866
  this.redisCounters = new Map();
799
867
  this.eventHubs = new Map();
800
868
  this.eventHubOffsets = new Map();
869
+ this.sqsQueues = new Map();
801
870
  this.pushTopics = new Map();
802
871
  this.pushOffsets = new Map();
803
872
  }
@@ -812,6 +881,7 @@ const protocolBus = new class InMemoryProtocolBus {
812
881
  this.redisCounters.clear();
813
882
  this.eventHubs.clear();
814
883
  this.eventHubOffsets.clear();
884
+ this.sqsQueues.clear();
815
885
  this.pushTopics.clear();
816
886
  this.pushOffsets.clear();
817
887
  }
@@ -976,6 +1046,25 @@ const protocolBus = new class InMemoryProtocolBus {
976
1046
  this.eventHubOffsets.set(cursorKey, rows.length);
977
1047
  return null;
978
1048
  }
1049
+ produceSqs(endpoint, payload) {
1050
+ const options = endpoint.sqs ?? {};
1051
+ const queueUrl = optionString(options, "QueueUrl", "queueUrl") || endpoint.name;
1052
+ const queue = this.sqsQueues.get(queueUrl) ?? [];
1053
+ queue.push({ payload: clonePayload(payload), timestampMs: Date.now() });
1054
+ this.sqsQueues.set(queueUrl, queue);
1055
+ return clonePayload(payload);
1056
+ }
1057
+ consumeSqs(endpoint) {
1058
+ const options = endpoint.sqs ?? {};
1059
+ const queueUrl = optionString(options, "QueueUrl", "queueUrl") || endpoint.name;
1060
+ const queue = this.sqsQueues.get(queueUrl) ?? [];
1061
+ if (!queue.length) {
1062
+ return null;
1063
+ }
1064
+ const next = queue.shift() ?? null;
1065
+ this.sqsQueues.set(queueUrl, queue);
1066
+ return next ? clonePayload(next.payload) : null;
1067
+ }
979
1068
  producePush(endpoint, payload) {
980
1069
  const options = endpoint.pushDiffusion ?? {};
981
1070
  const topic = optionString(options, "TopicPath", "topicPath")
@@ -1717,6 +1806,104 @@ class AzureEventHubsEndpointAdapter extends CallbackAdapter {
1717
1806
  await this.subscriptionPromise;
1718
1807
  }
1719
1808
  }
1809
+ let sqsClientFactoryForTests = null;
1810
+ class SqsEndpointAdapter extends CallbackAdapter {
1811
+ constructor() {
1812
+ super(...arguments);
1813
+ this.clientPromise = null;
1814
+ }
1815
+ async produce(payload) {
1816
+ if (resolveProduceDelegate(this.endpoint)) {
1817
+ return super.produce(payload);
1818
+ }
1819
+ if (this.endpoint.mode !== "Produce") {
1820
+ return null;
1821
+ }
1822
+ const client = await this.getClient();
1823
+ const options = this.endpoint.sqs ?? {};
1824
+ const resolved = prepareProducedPayload(this.endpoint, payload);
1825
+ const wire = toWirePayload(resolved, this.endpoint);
1826
+ const { SendMessageCommand } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-sqs")));
1827
+ await client.send(new SendMessageCommand({
1828
+ QueueUrl: optionString(options, "QueueUrl", "queueUrl"),
1829
+ MessageBody: payloadBodyAsUtf8(wire.body),
1830
+ MessageAttributes: toSqsMessageAttributes(wire.headers, wire.contentType)
1831
+ }));
1832
+ return clonePayload(resolved);
1833
+ }
1834
+ async consume() {
1835
+ if (resolveConsumeDelegate(this.endpoint)) {
1836
+ return super.consume();
1837
+ }
1838
+ if (this.endpoint.mode !== "Consume") {
1839
+ return null;
1840
+ }
1841
+ const client = await this.getClient();
1842
+ const options = this.endpoint.sqs ?? {};
1843
+ const { ReceiveMessageCommand, DeleteMessageCommand } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-sqs")));
1844
+ const input = {
1845
+ QueueUrl: optionString(options, "QueueUrl", "queueUrl"),
1846
+ MaxNumberOfMessages: hasOptionValue(options, "MaxNumberOfMessages", "maxNumberOfMessages")
1847
+ ? optionNumber(options, "MaxNumberOfMessages", "maxNumberOfMessages")
1848
+ : 1,
1849
+ WaitTimeSeconds: hasOptionValue(options, "WaitTimeSeconds", "waitTimeSeconds")
1850
+ ? optionNumber(options, "WaitTimeSeconds", "waitTimeSeconds")
1851
+ : 1,
1852
+ MessageAttributeNames: ["All"]
1853
+ };
1854
+ const visibilityTimeout = optionNumber(options, "VisibilityTimeoutSeconds", "visibilityTimeoutSeconds");
1855
+ if (visibilityTimeout > 0) {
1856
+ input.VisibilityTimeout = visibilityTimeout;
1857
+ }
1858
+ const response = await client.send(new ReceiveMessageCommand(input));
1859
+ const message = response.Messages?.[0];
1860
+ if (!message) {
1861
+ return null;
1862
+ }
1863
+ const { headers, contentType } = fromSqsMessageAttributes(message.MessageAttributes);
1864
+ const payload = createBrokerPayload(headers, Buffer.from(message.Body ?? "", "utf8"), this.endpoint, contentType);
1865
+ if (optionBoolean(options, true, "DeleteAfterConsume", "deleteAfterConsume") && message.ReceiptHandle) {
1866
+ await client.send(new DeleteMessageCommand({
1867
+ QueueUrl: optionString(options, "QueueUrl", "queueUrl"),
1868
+ ReceiptHandle: message.ReceiptHandle
1869
+ }));
1870
+ }
1871
+ return payload;
1872
+ }
1873
+ async dispose() {
1874
+ const client = await this.clientPromise?.catch(() => null);
1875
+ client?.destroy?.();
1876
+ }
1877
+ async getClient() {
1878
+ if (!this.clientPromise) {
1879
+ this.clientPromise = (async () => {
1880
+ if (sqsClientFactoryForTests) {
1881
+ return await sqsClientFactoryForTests(this.endpoint);
1882
+ }
1883
+ const { SQSClient } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-sqs")));
1884
+ const options = this.endpoint.sqs ?? {};
1885
+ const accessKeyId = optionString(options, "AccessKeyId", "accessKeyId");
1886
+ const secretAccessKey = optionString(options, "SecretAccessKey", "secretAccessKey");
1887
+ const config = {
1888
+ region: optionString(options, "Region", "region")
1889
+ };
1890
+ const serviceUrl = optionString(options, "ServiceUrl", "serviceUrl");
1891
+ if (serviceUrl) {
1892
+ config.endpoint = serviceUrl;
1893
+ }
1894
+ if (accessKeyId) {
1895
+ config.credentials = {
1896
+ accessKeyId,
1897
+ secretAccessKey,
1898
+ sessionToken: optionString(options, "SessionToken", "sessionToken") || undefined
1899
+ };
1900
+ }
1901
+ return new SQSClient(config);
1902
+ })();
1903
+ }
1904
+ return this.clientPromise;
1905
+ }
1906
+ }
1720
1907
  class PushDiffusionEndpointAdapter extends CallbackAdapter {
1721
1908
  async produce(payload) {
1722
1909
  return super.produce(payload);
@@ -1747,6 +1934,8 @@ class EndpointAdapterFactory {
1747
1934
  return new RedisStreamsEndpointAdapter(normalized);
1748
1935
  case "AzureEventHubs":
1749
1936
  return new AzureEventHubsEndpointAdapter(normalized);
1937
+ case "Sqs":
1938
+ return new SqsEndpointAdapter(normalized);
1750
1939
  case "PushDiffusion":
1751
1940
  return new PushDiffusionEndpointAdapter(normalized);
1752
1941
  case "DelegateStream":
@@ -1875,6 +2064,28 @@ const AZURE_EVENT_HUBS_ENDPOINT_FLAT_KEYS = [
1875
2064
  "StartFromEarliest",
1876
2065
  "startFromEarliest"
1877
2066
  ];
2067
+ const SQS_ENDPOINT_FLAT_KEYS = [
2068
+ "QueueUrl",
2069
+ "queueUrl",
2070
+ "Region",
2071
+ "region",
2072
+ "ServiceUrl",
2073
+ "serviceUrl",
2074
+ "AccessKeyId",
2075
+ "accessKeyId",
2076
+ "SecretAccessKey",
2077
+ "secretAccessKey",
2078
+ "SessionToken",
2079
+ "sessionToken",
2080
+ "WaitTimeSeconds",
2081
+ "waitTimeSeconds",
2082
+ "MaxNumberOfMessages",
2083
+ "maxNumberOfMessages",
2084
+ "VisibilityTimeoutSeconds",
2085
+ "visibilityTimeoutSeconds",
2086
+ "DeleteAfterConsume",
2087
+ "deleteAfterConsume"
2088
+ ];
1878
2089
  const PUSH_DIFFUSION_ENDPOINT_FLAT_KEYS = [
1879
2090
  "ServerUrl",
1880
2091
  "serverUrl",
@@ -1935,6 +2146,7 @@ function normalizeEndpointDefinition(endpoint) {
1935
2146
  nats: normalizeProtocolOptions(pickEndpointTransportRecord(raw, kind, "Nats", ["nats", "Nats"], NATS_ENDPOINT_FLAT_KEYS)),
1936
2147
  redisStreams: normalizeProtocolOptions(pickEndpointTransportRecord(raw, kind, "RedisStreams", ["redisStreams", "RedisStreams"], REDIS_STREAMS_ENDPOINT_FLAT_KEYS)),
1937
2148
  azureEventHubs: normalizeProtocolOptions(pickEndpointTransportRecord(raw, kind, "AzureEventHubs", ["azureEventHubs", "AzureEventHubs"], AZURE_EVENT_HUBS_ENDPOINT_FLAT_KEYS)),
2149
+ sqs: normalizeProtocolOptions(pickEndpointTransportRecord(raw, kind, "Sqs", ["sqs", "Sqs"], SQS_ENDPOINT_FLAT_KEYS)),
1938
2150
  pushDiffusion: normalizeProtocolOptions(pickEndpointTransportRecord(raw, kind, "PushDiffusion", ["pushDiffusion", "PushDiffusion"], PUSH_DIFFUSION_ENDPOINT_FLAT_KEYS)),
1939
2151
  delegate: normalizeDelegateEndpointOptions(pickEndpointTransportRecord(raw, kind, "DelegateStream", ["delegate", "Delegate", "DelegateStream"], DELEGATE_STREAM_ENDPOINT_FLAT_KEYS))
1940
2152
  };
@@ -1992,6 +2204,22 @@ function resolveEndpointKind(raw) {
1992
2204
  ])) {
1993
2205
  return "AzureEventHubs";
1994
2206
  }
2207
+ if (Object.keys(pickEndpointRecord(raw, "sqs", "Sqs")).length || hasAnyEndpointField(raw, [
2208
+ "QueueUrl",
2209
+ "queueUrl",
2210
+ "ServiceUrl",
2211
+ "serviceUrl",
2212
+ "WaitTimeSeconds",
2213
+ "waitTimeSeconds",
2214
+ "MaxNumberOfMessages",
2215
+ "maxNumberOfMessages",
2216
+ "VisibilityTimeoutSeconds",
2217
+ "visibilityTimeoutSeconds",
2218
+ "DeleteAfterConsume",
2219
+ "deleteAfterConsume"
2220
+ ])) {
2221
+ return "Sqs";
2222
+ }
1995
2223
  if (Object.keys(pickEndpointRecord(raw, "pushDiffusion", "PushDiffusion")).length || hasAnyEndpointField(raw, [
1996
2224
  "TopicPath",
1997
2225
  "topicPath",
@@ -2273,6 +2501,9 @@ function validateEndpointDefinition(endpoint) {
2273
2501
  case "AzureEventHubs":
2274
2502
  validateAzureEventHubsEndpoint(endpoint, mode, hasModeDelegate);
2275
2503
  return;
2504
+ case "Sqs":
2505
+ validateSqsEndpoint(endpoint, mode, hasModeDelegate);
2506
+ return;
2276
2507
  case "PushDiffusion":
2277
2508
  validatePushDiffusionEndpoint(endpoint, mode);
2278
2509
  return;
@@ -2494,6 +2725,32 @@ function validateAzureEventHubsEndpoint(endpoint, mode, hasModeDelegate) {
2494
2725
  throw new RangeError("PartitionCount must be zero or greater when configured.");
2495
2726
  }
2496
2727
  }
2728
+ function validateSqsEndpoint(endpoint, mode, hasModeDelegate) {
2729
+ const options = endpoint.sqs;
2730
+ if ((!options || typeof options !== "object") && !hasModeDelegate) {
2731
+ throw new Error(`Sqs endpoint in ${mode} mode requires sqs options or delegate callback.`);
2732
+ }
2733
+ if (!options || typeof options !== "object") {
2734
+ return;
2735
+ }
2736
+ requireNonEmptyString(optionString(options, "QueueUrl", "queueUrl"), "QueueUrl must be provided for AWS SQS endpoint.");
2737
+ requireNonEmptyString(optionString(options, "Region", "region"), "Region must be provided for AWS SQS endpoint.");
2738
+ if (optionString(options, "AccessKeyId", "accessKeyId") && !optionString(options, "SecretAccessKey", "secretAccessKey")) {
2739
+ throw new Error("SecretAccessKey must be provided when AccessKeyId is configured for AWS SQS endpoint.");
2740
+ }
2741
+ const waitTimeSeconds = optionNumber(options, "WaitTimeSeconds", "waitTimeSeconds");
2742
+ if (waitTimeSeconds < 0 || waitTimeSeconds > 20) {
2743
+ throw new RangeError("WaitTimeSeconds must be between 0 and 20 for AWS SQS endpoint.");
2744
+ }
2745
+ const maxNumberOfMessages = optionNumber(options, "MaxNumberOfMessages", "maxNumberOfMessages") || 1;
2746
+ if (maxNumberOfMessages <= 0 || maxNumberOfMessages > 10) {
2747
+ throw new RangeError("MaxNumberOfMessages must be between 1 and 10 for AWS SQS endpoint.");
2748
+ }
2749
+ const visibilityTimeoutSeconds = optionNumber(options, "VisibilityTimeoutSeconds", "visibilityTimeoutSeconds");
2750
+ if (visibilityTimeoutSeconds < 0) {
2751
+ throw new RangeError("VisibilityTimeoutSeconds must be zero or greater when configured.");
2752
+ }
2753
+ }
2497
2754
  function validatePushDiffusionEndpoint(endpoint, mode) {
2498
2755
  const options = endpoint.pushDiffusion;
2499
2756
  if (!options || typeof options !== "object") {
@@ -2858,6 +3115,12 @@ function optionNumber(options, ...keys) {
2858
3115
  }
2859
3116
  return 0;
2860
3117
  }
3118
+ function hasOptionValue(options, ...keys) {
3119
+ return keys.some((key) => {
3120
+ const value = options[key];
3121
+ return value !== undefined && value !== null && (!(typeof value === "string") || value.trim() !== "");
3122
+ });
3123
+ }
2861
3124
  function optionBoolean(options, fallback, ...keys) {
2862
3125
  for (const key of keys) {
2863
3126
  const value = options[key];
@@ -3741,6 +4004,29 @@ function createRedisStreamPayload(fields, endpoint) {
3741
4004
  }
3742
4005
  return createBrokerPayload(headers, body, endpoint, contentType);
3743
4006
  }
4007
+ function toSqsMessageAttributes(headers, contentType) {
4008
+ const attributes = {};
4009
+ for (const [key, value] of Object.entries(headers)) {
4010
+ attributes[key] = { DataType: "String", StringValue: String(value ?? "") };
4011
+ }
4012
+ if (contentType) {
4013
+ attributes["content-type"] = { DataType: "String", StringValue: contentType };
4014
+ }
4015
+ return attributes;
4016
+ }
4017
+ function fromSqsMessageAttributes(attributes) {
4018
+ const headers = {};
4019
+ let contentType;
4020
+ for (const [key, value] of Object.entries(attributes ?? {})) {
4021
+ const text = String(value?.StringValue ?? "");
4022
+ if (key.toLowerCase() === "content-type") {
4023
+ contentType = text;
4024
+ continue;
4025
+ }
4026
+ headers[key] = text;
4027
+ }
4028
+ return { headers, contentType };
4029
+ }
3744
4030
  function payloadBodyAsUtf8(body) {
3745
4031
  if (body instanceof Uint8Array) {
3746
4032
  return new TextDecoder().decode(body);
@@ -3775,6 +4061,9 @@ exports.__loadstrikeTestExports = {
3775
4061
  RedisStreamsEndpointAdapter,
3776
4062
  RedisStreamsEndpointDefinition: exports.RedisStreamsEndpointDefinition,
3777
4063
  RedisStreamsEndpointDefinitionModel,
4064
+ SqsEndpointAdapter,
4065
+ SqsEndpointDefinition: exports.SqsEndpointDefinition,
4066
+ SqsEndpointDefinitionModel,
3778
4067
  bufferToUint8Array,
3779
4068
  applyHttpAuthHeaders,
3780
4069
  buildHttpRequestBody,
@@ -3809,6 +4098,11 @@ exports.__loadstrikeTestExports = {
3809
4098
  shouldUseConfluentKafkaClient,
3810
4099
  toHeaderRecord,
3811
4100
  toKafkaHeadersWithContentType,
4101
+ toSqsMessageAttributes,
4102
+ fromSqsMessageAttributes,
4103
+ setSqsClientFactoryForTests: (factory) => {
4104
+ sqsClientFactoryForTests = factory;
4105
+ },
3812
4106
  validateHttpEndpoint,
3813
4107
  validateTrackingSelectorPath
3814
4108
  };
@@ -12,11 +12,13 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
12
12
  var _LoadStrikeAutopilotResult_httpRequest;
13
13
  import fs from "node:fs";
14
14
  import { LoadStrikeResponse, LoadStrikeScenario, LoadStrikeSimulation, LoadStrikeThreshold } from "./runtime.js";
15
+ import { LoadStrikeLocalClient } from "./local.js";
15
16
  import { LoadStrikeAutopilotReadiness } from "./autopilot-contracts.js";
16
17
  const REDACTED = "[REDACTED]";
17
18
  const ENV_MARKER_PREFIX = "${LOADSTRIKE_ENV:";
18
19
  const ENV_MARKER_SUFFIX = "}";
19
20
  const TRACE_TO_TEST_AUTOPILOT_FEATURE = "autopilot.trace_to_test";
21
+ let autopilotLicenseValidationBypassForTests = false;
20
22
  const SECRET_KEYS = new Set([
21
23
  "authorization",
22
24
  "proxy_authorization",
@@ -88,9 +90,10 @@ export class LoadStrikeAutopilotResult {
88
90
  }
89
91
  _LoadStrikeAutopilotResult_httpRequest = new WeakMap();
90
92
  export class LoadStrikeAutopilot {
91
- static generate(request) {
93
+ static async generate(request) {
92
94
  const artifact = loadAutopilotArtifact(request);
93
95
  const options = request.Options ?? {};
96
+ await validateGenerationEntitlement(options);
94
97
  const result = inferAutopilotResult(artifact, options);
95
98
  if (options.IncludePreviewReport) {
96
99
  result.PreviewReport = buildPreviewReport(result);
@@ -101,6 +104,57 @@ export class LoadStrikeAutopilot {
101
104
  return LoadStrikeAutopilot.generate(request);
102
105
  }
103
106
  }
107
+ export const __private = {
108
+ setAutopilotLicenseValidationBypassForTests(value) {
109
+ autopilotLicenseValidationBypassForTests = value;
110
+ }
111
+ };
112
+ async function validateGenerationEntitlement(options) {
113
+ if (autopilotLicenseValidationBypassForTests) {
114
+ return;
115
+ }
116
+ const licensePayload = {
117
+ Context: {
118
+ RunnerKey: options.RunnerKey ?? "",
119
+ LicenseValidationTimeoutSeconds: options.LicenseValidationTimeoutSeconds,
120
+ TestSuite: "loadstrike-autopilot",
121
+ TestName: options.ScenarioName?.trim() || "autopilot-generation"
122
+ },
123
+ Scenarios: [
124
+ {
125
+ Name: "autopilot-generation",
126
+ InternalLicenseFeatures: [TRACE_TO_TEST_AUTOPILOT_FEATURE]
127
+ }
128
+ ],
129
+ RunArgs: []
130
+ };
131
+ const client = new LoadStrikeLocalClient({
132
+ licenseValidationTimeoutMs: normalizeLicenseValidationTimeoutMs(options.LicenseValidationTimeoutSeconds)
133
+ });
134
+ let session;
135
+ try {
136
+ session = await client.acquireLicenseLease(licensePayload);
137
+ }
138
+ catch (error) {
139
+ const message = error instanceof Error ? error.message : String(error);
140
+ if (message.toLowerCase().includes("runner key is required")) {
141
+ throw new Error("Runner key is required for Trace-To-Test Autopilot generation. " +
142
+ "Set Options.RunnerKey before calling LoadStrikeAutopilot.generate(...).");
143
+ }
144
+ throw error;
145
+ }
146
+ finally {
147
+ if (session) {
148
+ await client.releaseLicenseLease(session, licensePayload);
149
+ }
150
+ }
151
+ }
152
+ function normalizeLicenseValidationTimeoutMs(value) {
153
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
154
+ return undefined;
155
+ }
156
+ return Math.trunc(value * 1000);
157
+ }
104
158
  function loadAutopilotArtifact(request) {
105
159
  if (!request || typeof request.Kind !== "string" || !request.Kind.trim()) {
106
160
  throw new Error("Autopilot kind must be provided.");
package/dist/esm/index.js CHANGED
@@ -2,5 +2,5 @@ export { LoadStrikeAutopilot, LoadStrikeAutopilotResult } from "./autopilot.js";
2
2
  export { LoadStrikeAutopilotReadiness } from "./autopilot-contracts.js";
3
3
  export { CrossPlatformScenarioConfigurator, ScenarioTrackingExtensions, LoadStrikeContext, LoadStrikePluginData, LoadStrikePluginDataTable, LoadStrikeNodeType, LoadStrikeReportFormat, LoadStrikeResponse, LoadStrikeLogLevel, LoadStrikeScenarioOperation, LoadStrikeOperationType, LoadStrikeRunner, LoadStrikeScenario, LoadStrikeSimulation, CrossPlatformTrackingConfiguration, LoadStrikeMetric, LoadStrikeCounter, LoadStrikeGauge, LoadStrikeStep, LoadStrikeThreshold } from "./runtime.js";
4
4
  export { CorrelationStoreConfiguration, CrossPlatformTrackingRuntime, InMemoryCorrelationStore, RedisCorrelationStoreOptions, RedisCorrelationStore, TrackingPayloadBuilder, TrackingFieldSelector } from "./correlation.js";
5
- export { EndpointAdapterFactory, LOADSTRIKE_TRACE_ID_HEADER, LOADSTRIKE_TRACE_ID_TRACKING_FIELD, TrafficEndpointDefinition, HttpEndpointDefinition, KafkaEndpointDefinition, KafkaSaslOptions, RabbitMqEndpointDefinition, NatsEndpointDefinition, RedisStreamsEndpointDefinition, AzureEventHubsEndpointDefinition, DelegateStreamEndpointDefinition, PushDiffusionEndpointDefinition, HttpOAuth2ClientCredentialsOptions, HttpAuthOptions } from "./transports.js";
5
+ export { LOADSTRIKE_TRACE_ID_HEADER, LOADSTRIKE_TRACE_ID_TRACKING_FIELD, TrafficEndpointDefinition, HttpEndpointDefinition, KafkaEndpointDefinition, KafkaSaslOptions, RabbitMqEndpointDefinition, NatsEndpointDefinition, RedisStreamsEndpointDefinition, AzureEventHubsEndpointDefinition, SqsEndpointDefinition, DelegateStreamEndpointDefinition, PushDiffusionEndpointDefinition, HttpOAuth2ClientCredentialsOptions, HttpAuthOptions } from "./transports.js";
6
6
  export { DatadogReportingSink, DatadogReportingSinkOptions, GrafanaLokiReportingSink, GrafanaLokiReportingSinkOptions, InfluxDbReportingSink, InfluxDbReportingSinkOptions, OtelCollectorReportingSink, OtelCollectorReportingSinkOptions, SplunkReportingSink, SplunkReportingSinkOptions, TimescaleDbReportingSink, TimescaleDbReportingSinkOptions } from "./sinks.js";