agent-relay 4.0.20 → 4.0.22

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 (59) hide show
  1. package/README.md +8 -0
  2. package/dist/src/cli/commands/messaging.d.ts +44 -0
  3. package/dist/src/cli/commands/messaging.d.ts.map +1 -1
  4. package/dist/src/cli/commands/messaging.js +195 -8
  5. package/dist/src/cli/commands/messaging.js.map +1 -1
  6. package/dist/src/cli/lib/ssh-interactive.d.ts +11 -0
  7. package/dist/src/cli/lib/ssh-interactive.d.ts.map +1 -1
  8. package/dist/src/cli/lib/ssh-interactive.js +53 -26
  9. package/dist/src/cli/lib/ssh-interactive.js.map +1 -1
  10. package/node_modules/@agent-relay/cloud/dist/auth.d.ts +2 -2
  11. package/node_modules/@agent-relay/cloud/dist/auth.d.ts.map +1 -1
  12. package/node_modules/@agent-relay/cloud/dist/auth.js +108 -62
  13. package/node_modules/@agent-relay/cloud/dist/auth.js.map +1 -1
  14. package/node_modules/@agent-relay/cloud/package.json +2 -2
  15. package/node_modules/@agent-relay/config/package.json +1 -1
  16. package/node_modules/@agent-relay/hooks/package.json +4 -4
  17. package/node_modules/@agent-relay/sdk/package.json +2 -2
  18. package/node_modules/@agent-relay/telemetry/package.json +1 -1
  19. package/node_modules/@agent-relay/trajectory/package.json +2 -2
  20. package/node_modules/@agent-relay/user-directory/package.json +2 -2
  21. package/node_modules/@agent-relay/utils/package.json +2 -2
  22. package/node_modules/@smithy/config-resolver/package.json +2 -2
  23. package/node_modules/@smithy/util-defaults-mode-node/package.json +2 -2
  24. package/node_modules/@smithy/util-endpoints/dist-cjs/index.js +154 -61
  25. package/node_modules/@smithy/util-endpoints/dist-es/bdd/BinaryDecisionDiagram.js +15 -0
  26. package/node_modules/@smithy/util-endpoints/dist-es/decideEndpoint.js +41 -0
  27. package/node_modules/@smithy/util-endpoints/dist-es/index.js +2 -0
  28. package/node_modules/@smithy/util-endpoints/dist-es/lib/coalesce.js +8 -0
  29. package/node_modules/@smithy/util-endpoints/dist-es/lib/index.js +3 -0
  30. package/node_modules/@smithy/util-endpoints/dist-es/lib/ite.js +3 -0
  31. package/node_modules/@smithy/util-endpoints/dist-es/lib/split.js +13 -0
  32. package/node_modules/@smithy/util-endpoints/dist-es/lib/substring.js +1 -1
  33. package/node_modules/@smithy/util-endpoints/dist-es/utils/endpointFunctions.js +4 -1
  34. package/node_modules/@smithy/util-endpoints/dist-es/utils/evaluateExpression.js +20 -5
  35. package/node_modules/@smithy/util-endpoints/dist-es/utils/evaluateTemplate.js +3 -6
  36. package/node_modules/@smithy/util-endpoints/dist-es/utils/getReferenceValue.js +1 -5
  37. package/node_modules/@smithy/util-endpoints/dist-types/bdd/BinaryDecisionDiagram.d.ts +22 -0
  38. package/node_modules/@smithy/util-endpoints/dist-types/decideEndpoint.d.ts +7 -0
  39. package/node_modules/@smithy/util-endpoints/dist-types/index.d.ts +2 -0
  40. package/node_modules/@smithy/util-endpoints/dist-types/lib/coalesce.d.ts +7 -0
  41. package/node_modules/@smithy/util-endpoints/dist-types/lib/index.d.ts +3 -0
  42. package/node_modules/@smithy/util-endpoints/dist-types/lib/ite.d.ts +6 -0
  43. package/node_modules/@smithy/util-endpoints/dist-types/lib/split.d.ts +11 -0
  44. package/node_modules/@smithy/util-endpoints/dist-types/utils/endpointFunctions.d.ts +4 -0
  45. package/node_modules/@smithy/util-endpoints/dist-types/utils/getReferenceValue.d.ts +3 -1
  46. package/node_modules/@smithy/util-endpoints/package.json +1 -1
  47. package/package.json +11 -10
  48. package/packages/cloud/dist/auth.d.ts +2 -2
  49. package/packages/cloud/dist/auth.d.ts.map +1 -1
  50. package/packages/cloud/dist/auth.js +108 -62
  51. package/packages/cloud/dist/auth.js.map +1 -1
  52. package/packages/cloud/package.json +2 -2
  53. package/packages/config/package.json +1 -1
  54. package/packages/hooks/package.json +4 -4
  55. package/packages/sdk/package.json +2 -2
  56. package/packages/telemetry/package.json +1 -1
  57. package/packages/trajectory/package.json +2 -2
  58. package/packages/user-directory/package.json +2 -2
  59. package/packages/utils/package.json +2 -2
@@ -2,6 +2,22 @@
2
2
 
3
3
  var types = require('@smithy/types');
4
4
 
5
+ class BinaryDecisionDiagram {
6
+ nodes;
7
+ root;
8
+ conditions;
9
+ results;
10
+ constructor(bdd, root, conditions, results) {
11
+ this.nodes = bdd;
12
+ this.root = root;
13
+ this.conditions = conditions;
14
+ this.results = results;
15
+ }
16
+ static from(bdd, root, conditions, results) {
17
+ return new BinaryDecisionDiagram(bdd, root, conditions, results);
18
+ }
19
+ }
20
+
5
21
  class EndpointCache {
6
22
  capacity;
7
23
  data = new Map();
@@ -53,24 +69,12 @@ class EndpointCache {
53
69
  }
54
70
  }
55
71
 
56
- const IP_V4_REGEX = new RegExp(`^(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}$`);
57
- const isIpAddress = (value) => IP_V4_REGEX.test(value) || (value.startsWith("[") && value.endsWith("]"));
58
-
59
- const VALID_HOST_LABEL_REGEX = new RegExp(`^(?!.*-$)(?!-)[a-zA-Z0-9-]{1,63}$`);
60
- const isValidHostLabel = (value, allowSubDomains = false) => {
61
- if (!allowSubDomains) {
62
- return VALID_HOST_LABEL_REGEX.test(value);
63
- }
64
- const labels = value.split(".");
65
- for (const label of labels) {
66
- if (!isValidHostLabel(label)) {
67
- return false;
68
- }
72
+ class EndpointError extends Error {
73
+ constructor(message) {
74
+ super(message);
75
+ this.name = "EndpointError";
69
76
  }
70
- return true;
71
- };
72
-
73
- const customEndpointFunctions = {};
77
+ }
74
78
 
75
79
  const debugId = "endpoints";
76
80
 
@@ -87,15 +91,19 @@ function toDebugString(input) {
87
91
  return JSON.stringify(input, null, 2);
88
92
  }
89
93
 
90
- class EndpointError extends Error {
91
- constructor(message) {
92
- super(message);
93
- this.name = "EndpointError";
94
- }
95
- }
94
+ const customEndpointFunctions = {};
96
95
 
97
96
  const booleanEquals = (value1, value2) => value1 === value2;
98
97
 
98
+ function coalesce(...args) {
99
+ for (const arg of args) {
100
+ if (arg != null) {
101
+ return arg;
102
+ }
103
+ }
104
+ return undefined;
105
+ }
106
+
99
107
  const getAttrPathList = (path) => {
100
108
  const parts = path.split(".");
101
109
  const pathList = [];
@@ -133,8 +141,29 @@ const getAttr = (value, path) => getAttrPathList(path).reduce((acc, index) => {
133
141
 
134
142
  const isSet = (value) => value != null;
135
143
 
144
+ const VALID_HOST_LABEL_REGEX = new RegExp(`^(?!.*-$)(?!-)[a-zA-Z0-9-]{1,63}$`);
145
+ const isValidHostLabel = (value, allowSubDomains = false) => {
146
+ if (!allowSubDomains) {
147
+ return VALID_HOST_LABEL_REGEX.test(value);
148
+ }
149
+ const labels = value.split(".");
150
+ for (const label of labels) {
151
+ if (!isValidHostLabel(label)) {
152
+ return false;
153
+ }
154
+ }
155
+ return true;
156
+ };
157
+
158
+ function ite(condition, trueValue, falseValue) {
159
+ return condition ? trueValue : falseValue;
160
+ }
161
+
136
162
  const not = (value) => !value;
137
163
 
164
+ const IP_V4_REGEX = new RegExp(`^(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}$`);
165
+ const isIpAddress = (value) => IP_V4_REGEX.test(value) || (value.startsWith("[") && value.endsWith("]"));
166
+
138
167
  const DEFAULT_PORTS = {
139
168
  [types.EndpointURLScheme.HTTP]: 80,
140
169
  [types.EndpointURLScheme.HTTPS]: 443,
@@ -185,10 +214,24 @@ const parseURL = (value) => {
185
214
  };
186
215
  };
187
216
 
217
+ function split(value, delimiter, limit) {
218
+ if (limit === 1) {
219
+ return [value];
220
+ }
221
+ if (value === "") {
222
+ return [""];
223
+ }
224
+ const parts = value.split(delimiter);
225
+ if (limit === 0) {
226
+ return parts;
227
+ }
228
+ return parts.slice(0, limit - 1).concat(parts.slice(1).join(delimiter));
229
+ }
230
+
188
231
  const stringEquals = (value1, value2) => value1 === value2;
189
232
 
190
233
  const substring = (input, start, stop, reverse) => {
191
- if (start >= stop || input.length < stop || /[^\u0000-\u007f]/.test(input)) {
234
+ if (input == null || start >= stop || input.length < stop || /[^\u0000-\u007f]/.test(input)) {
192
235
  return null;
193
236
  }
194
237
  if (!reverse) {
@@ -201,11 +244,14 @@ const uriEncode = (value) => encodeURIComponent(value).replace(/[!*'()]/g, (c) =
201
244
 
202
245
  const endpointFunctions = {
203
246
  booleanEquals,
247
+ coalesce,
204
248
  getAttr,
205
249
  isSet,
206
250
  isValidHostLabel,
251
+ ite,
207
252
  not,
208
253
  parseURL,
254
+ split,
209
255
  stringEquals,
210
256
  substring,
211
257
  uriEncode,
@@ -213,10 +259,7 @@ const endpointFunctions = {
213
259
 
214
260
  const evaluateTemplate = (template, options) => {
215
261
  const evaluatedTemplateArr = [];
216
- const templateContext = {
217
- ...options.endpointParams,
218
- ...options.referenceRecord,
219
- };
262
+ const { referenceRecord, endpointParams } = options;
220
263
  let currentIndex = 0;
221
264
  while (currentIndex < template.length) {
222
265
  const openingBraceIndex = template.indexOf("{", currentIndex);
@@ -237,10 +280,10 @@ const evaluateTemplate = (template, options) => {
237
280
  const parameterName = template.substring(openingBraceIndex + 1, closingBraceIndex);
238
281
  if (parameterName.includes("#")) {
239
282
  const [refName, attrName] = parameterName.split("#");
240
- evaluatedTemplateArr.push(getAttr(templateContext[refName], attrName));
283
+ evaluatedTemplateArr.push(getAttr((referenceRecord[refName] ?? endpointParams[refName]), attrName));
241
284
  }
242
285
  else {
243
- evaluatedTemplateArr.push(templateContext[parameterName]);
286
+ evaluatedTemplateArr.push((referenceRecord[parameterName] ?? endpointParams[parameterName]));
244
287
  }
245
288
  currentIndex = closingBraceIndex + 1;
246
289
  }
@@ -248,11 +291,7 @@ const evaluateTemplate = (template, options) => {
248
291
  };
249
292
 
250
293
  const getReferenceValue = ({ ref }, options) => {
251
- const referenceRecord = {
252
- ...options.endpointParams,
253
- ...options.referenceRecord,
254
- };
255
- return referenceRecord[ref];
294
+ return options.referenceRecord[ref] ?? options.endpointParams[ref];
256
295
  };
257
296
 
258
297
  const evaluateExpression = (obj, keyName, options) => {
@@ -268,12 +307,27 @@ const evaluateExpression = (obj, keyName, options) => {
268
307
  throw new EndpointError(`'${keyName}': ${String(obj)} is not a string, function or reference.`);
269
308
  };
270
309
  const callFunction = ({ fn, argv }, options) => {
271
- const evaluatedArgs = argv.map((arg) => ["boolean", "number"].includes(typeof arg) ? arg : group$2.evaluateExpression(arg, "arg", options));
272
- const fnSegments = fn.split(".");
273
- if (fnSegments[0] in customEndpointFunctions && fnSegments[1] != null) {
274
- return customEndpointFunctions[fnSegments[0]][fnSegments[1]](...evaluatedArgs);
310
+ const evaluatedArgs = Array(argv.length);
311
+ for (let i = 0; i < evaluatedArgs.length; ++i) {
312
+ const arg = argv[i];
313
+ if (typeof arg === "boolean" || typeof arg === "number") {
314
+ evaluatedArgs[i] = arg;
315
+ }
316
+ else {
317
+ evaluatedArgs[i] = group$2.evaluateExpression(arg, "arg", options);
318
+ }
275
319
  }
276
- return endpointFunctions[fn](...evaluatedArgs);
320
+ if (fn.includes(".")) {
321
+ const fnSegments = fn.split(".");
322
+ if (fnSegments[0] in customEndpointFunctions && fnSegments[1] != null) {
323
+ return customEndpointFunctions[fnSegments[0]][fnSegments[1]](...evaluatedArgs);
324
+ }
325
+ }
326
+ if (typeof endpointFunctions[fn] !== "function") {
327
+ throw new Error(`function ${fn} not loaded in endpointFunctions.`);
328
+ }
329
+ const callable = endpointFunctions[fn];
330
+ return callable(...evaluatedArgs);
277
331
  };
278
332
  const group$2 = {
279
333
  evaluateExpression,
@@ -292,27 +346,6 @@ const evaluateCondition = ({ assign, ...fnArgs }, options) => {
292
346
  };
293
347
  };
294
348
 
295
- const evaluateConditions = (conditions = [], options) => {
296
- const conditionsReferenceRecord = {};
297
- for (const condition of conditions) {
298
- const { result, toAssign } = evaluateCondition(condition, {
299
- ...options,
300
- referenceRecord: {
301
- ...options.referenceRecord,
302
- ...conditionsReferenceRecord,
303
- },
304
- });
305
- if (!result) {
306
- return { result };
307
- }
308
- if (toAssign) {
309
- conditionsReferenceRecord[toAssign.name] = toAssign.value;
310
- options.logger?.debug?.(`${debugId} assign: ${toAssign.name} := ${toDebugString(toAssign.value)}`);
311
- }
312
- }
313
- return { result: true, referenceRecord: conditionsReferenceRecord };
314
- };
315
-
316
349
  const getEndpointHeaders = (headers, options) => Object.entries(headers).reduce((acc, [headerKey, headerVal]) => ({
317
350
  ...acc,
318
351
  [headerKey]: headerVal.map((headerValEntry) => {
@@ -365,6 +398,64 @@ const getEndpointUrl = (endpointUrl, options) => {
365
398
  throw new EndpointError(`Endpoint URL must be a string, got ${typeof expression}`);
366
399
  };
367
400
 
401
+ const RESULT = 100_000_000;
402
+ const decideEndpoint = (bdd, options) => {
403
+ const { nodes, root, results, conditions } = bdd;
404
+ let ref = root;
405
+ const referenceRecord = {};
406
+ const closure = {
407
+ referenceRecord,
408
+ endpointParams: options.endpointParams,
409
+ logger: options.logger,
410
+ };
411
+ while (ref !== 1 && ref !== -1 && ref < RESULT) {
412
+ const node_i = 3 * (Math.abs(ref) - 1);
413
+ const [condition_i, highRef, lowRef] = [nodes[node_i], nodes[node_i + 1], nodes[node_i + 2]];
414
+ const [fn, argv, assign] = conditions[condition_i];
415
+ const evaluation = evaluateCondition({ fn, assign, argv }, closure);
416
+ if (evaluation.toAssign) {
417
+ const { name, value } = evaluation.toAssign;
418
+ referenceRecord[name] = value;
419
+ }
420
+ ref = ref >= 0 === evaluation.result ? highRef : lowRef;
421
+ }
422
+ if (ref >= RESULT) {
423
+ const result = results[ref - RESULT];
424
+ if (result[0] === -1) {
425
+ const [, errorMessage] = result;
426
+ throw new EndpointError(errorMessage);
427
+ }
428
+ const [url, properties, headers] = result;
429
+ return {
430
+ url: getEndpointUrl(url, closure),
431
+ properties: getEndpointProperties(properties, closure),
432
+ headers: getEndpointHeaders(headers, closure),
433
+ };
434
+ }
435
+ throw new EndpointError(`No matching endpoint.`);
436
+ };
437
+
438
+ const evaluateConditions = (conditions = [], options) => {
439
+ const conditionsReferenceRecord = {};
440
+ for (const condition of conditions) {
441
+ const { result, toAssign } = evaluateCondition(condition, {
442
+ ...options,
443
+ referenceRecord: {
444
+ ...options.referenceRecord,
445
+ ...conditionsReferenceRecord,
446
+ },
447
+ });
448
+ if (!result) {
449
+ return { result };
450
+ }
451
+ if (toAssign) {
452
+ conditionsReferenceRecord[toAssign.name] = toAssign.value;
453
+ options.logger?.debug?.(`${debugId} assign: ${toAssign.name} := ${toDebugString(toAssign.value)}`);
454
+ }
455
+ }
456
+ return { result: true, referenceRecord: conditionsReferenceRecord };
457
+ };
458
+
368
459
  const evaluateEndpointRule = (endpointRule, options) => {
369
460
  const { conditions, endpoint } = endpointRule;
370
461
  const { result, referenceRecord } = evaluateConditions(conditions, options);
@@ -464,9 +555,11 @@ const resolveEndpoint = (ruleSetObject, options) => {
464
555
  return endpoint;
465
556
  };
466
557
 
558
+ exports.BinaryDecisionDiagram = BinaryDecisionDiagram;
467
559
  exports.EndpointCache = EndpointCache;
468
560
  exports.EndpointError = EndpointError;
469
561
  exports.customEndpointFunctions = customEndpointFunctions;
562
+ exports.decideEndpoint = decideEndpoint;
470
563
  exports.isIpAddress = isIpAddress;
471
564
  exports.isValidHostLabel = isValidHostLabel;
472
565
  exports.resolveEndpoint = resolveEndpoint;
@@ -0,0 +1,15 @@
1
+ export class BinaryDecisionDiagram {
2
+ nodes;
3
+ root;
4
+ conditions;
5
+ results;
6
+ constructor(bdd, root, conditions, results) {
7
+ this.nodes = bdd;
8
+ this.root = root;
9
+ this.conditions = conditions;
10
+ this.results = results;
11
+ }
12
+ static from(bdd, root, conditions, results) {
13
+ return new BinaryDecisionDiagram(bdd, root, conditions, results);
14
+ }
15
+ }
@@ -0,0 +1,41 @@
1
+ import { EndpointError } from "./types";
2
+ import { evaluateCondition } from "./utils/evaluateCondition";
3
+ import { getEndpointHeaders } from "./utils/getEndpointHeaders";
4
+ import { getEndpointProperties } from "./utils/getEndpointProperties";
5
+ import { getEndpointUrl } from "./utils/getEndpointUrl";
6
+ const RESULT = 100_000_000;
7
+ export const decideEndpoint = (bdd, options) => {
8
+ const { nodes, root, results, conditions } = bdd;
9
+ let ref = root;
10
+ const referenceRecord = {};
11
+ const closure = {
12
+ referenceRecord,
13
+ endpointParams: options.endpointParams,
14
+ logger: options.logger,
15
+ };
16
+ while (ref !== 1 && ref !== -1 && ref < RESULT) {
17
+ const node_i = 3 * (Math.abs(ref) - 1);
18
+ const [condition_i, highRef, lowRef] = [nodes[node_i], nodes[node_i + 1], nodes[node_i + 2]];
19
+ const [fn, argv, assign] = conditions[condition_i];
20
+ const evaluation = evaluateCondition({ fn, assign, argv }, closure);
21
+ if (evaluation.toAssign) {
22
+ const { name, value } = evaluation.toAssign;
23
+ referenceRecord[name] = value;
24
+ }
25
+ ref = ref >= 0 === evaluation.result ? highRef : lowRef;
26
+ }
27
+ if (ref >= RESULT) {
28
+ const result = results[ref - RESULT];
29
+ if (result[0] === -1) {
30
+ const [, errorMessage] = result;
31
+ throw new EndpointError(errorMessage);
32
+ }
33
+ const [url, properties, headers] = result;
34
+ return {
35
+ url: getEndpointUrl(url, closure),
36
+ properties: getEndpointProperties(properties, closure),
37
+ headers: getEndpointHeaders(headers, closure),
38
+ };
39
+ }
40
+ throw new EndpointError(`No matching endpoint.`);
41
+ };
@@ -1,4 +1,6 @@
1
+ export { BinaryDecisionDiagram } from "./bdd/BinaryDecisionDiagram";
1
2
  export * from "./cache/EndpointCache";
3
+ export { decideEndpoint } from "./decideEndpoint";
2
4
  export * from "./lib/isIpAddress";
3
5
  export * from "./lib/isValidHostLabel";
4
6
  export * from "./utils/customEndpointFunctions";
@@ -0,0 +1,8 @@
1
+ export function coalesce(...args) {
2
+ for (const arg of args) {
3
+ if (arg != null) {
4
+ return arg;
5
+ }
6
+ }
7
+ return undefined;
8
+ }
@@ -1,9 +1,12 @@
1
1
  export * from "./booleanEquals";
2
+ export * from "./coalesce";
2
3
  export * from "./getAttr";
3
4
  export * from "./isSet";
4
5
  export * from "./isValidHostLabel";
6
+ export * from "./ite";
5
7
  export * from "./not";
6
8
  export * from "./parseURL";
9
+ export * from "./split";
7
10
  export * from "./stringEquals";
8
11
  export * from "./substring";
9
12
  export * from "./uriEncode";
@@ -0,0 +1,3 @@
1
+ export function ite(condition, trueValue, falseValue) {
2
+ return condition ? trueValue : falseValue;
3
+ }
@@ -0,0 +1,13 @@
1
+ export function split(value, delimiter, limit) {
2
+ if (limit === 1) {
3
+ return [value];
4
+ }
5
+ if (value === "") {
6
+ return [""];
7
+ }
8
+ const parts = value.split(delimiter);
9
+ if (limit === 0) {
10
+ return parts;
11
+ }
12
+ return parts.slice(0, limit - 1).concat(parts.slice(1).join(delimiter));
13
+ }
@@ -1,5 +1,5 @@
1
1
  export const substring = (input, start, stop, reverse) => {
2
- if (start >= stop || input.length < stop || /[^\u0000-\u007f]/.test(input)) {
2
+ if (input == null || start >= stop || input.length < stop || /[^\u0000-\u007f]/.test(input)) {
3
3
  return null;
4
4
  }
5
5
  if (!reverse) {
@@ -1,11 +1,14 @@
1
- import { booleanEquals, getAttr, isSet, isValidHostLabel, not, parseURL, stringEquals, substring, uriEncode, } from "../lib";
1
+ import { booleanEquals, coalesce, getAttr, isSet, isValidHostLabel, ite, not, parseURL, split, stringEquals, substring, uriEncode, } from "../lib";
2
2
  export const endpointFunctions = {
3
3
  booleanEquals,
4
+ coalesce,
4
5
  getAttr,
5
6
  isSet,
6
7
  isValidHostLabel,
8
+ ite,
7
9
  not,
8
10
  parseURL,
11
+ split,
9
12
  stringEquals,
10
13
  substring,
11
14
  uriEncode,
@@ -16,12 +16,27 @@ export const evaluateExpression = (obj, keyName, options) => {
16
16
  throw new EndpointError(`'${keyName}': ${String(obj)} is not a string, function or reference.`);
17
17
  };
18
18
  export const callFunction = ({ fn, argv }, options) => {
19
- const evaluatedArgs = argv.map((arg) => ["boolean", "number"].includes(typeof arg) ? arg : group.evaluateExpression(arg, "arg", options));
20
- const fnSegments = fn.split(".");
21
- if (fnSegments[0] in customEndpointFunctions && fnSegments[1] != null) {
22
- return customEndpointFunctions[fnSegments[0]][fnSegments[1]](...evaluatedArgs);
19
+ const evaluatedArgs = Array(argv.length);
20
+ for (let i = 0; i < evaluatedArgs.length; ++i) {
21
+ const arg = argv[i];
22
+ if (typeof arg === "boolean" || typeof arg === "number") {
23
+ evaluatedArgs[i] = arg;
24
+ }
25
+ else {
26
+ evaluatedArgs[i] = group.evaluateExpression(arg, "arg", options);
27
+ }
23
28
  }
24
- return endpointFunctions[fn](...evaluatedArgs);
29
+ if (fn.includes(".")) {
30
+ const fnSegments = fn.split(".");
31
+ if (fnSegments[0] in customEndpointFunctions && fnSegments[1] != null) {
32
+ return customEndpointFunctions[fnSegments[0]][fnSegments[1]](...evaluatedArgs);
33
+ }
34
+ }
35
+ if (typeof endpointFunctions[fn] !== "function") {
36
+ throw new Error(`function ${fn} not loaded in endpointFunctions.`);
37
+ }
38
+ const callable = endpointFunctions[fn];
39
+ return callable(...evaluatedArgs);
25
40
  };
26
41
  export const group = {
27
42
  evaluateExpression,
@@ -1,10 +1,7 @@
1
1
  import { getAttr } from "../lib";
2
2
  export const evaluateTemplate = (template, options) => {
3
3
  const evaluatedTemplateArr = [];
4
- const templateContext = {
5
- ...options.endpointParams,
6
- ...options.referenceRecord,
7
- };
4
+ const { referenceRecord, endpointParams } = options;
8
5
  let currentIndex = 0;
9
6
  while (currentIndex < template.length) {
10
7
  const openingBraceIndex = template.indexOf("{", currentIndex);
@@ -25,10 +22,10 @@ export const evaluateTemplate = (template, options) => {
25
22
  const parameterName = template.substring(openingBraceIndex + 1, closingBraceIndex);
26
23
  if (parameterName.includes("#")) {
27
24
  const [refName, attrName] = parameterName.split("#");
28
- evaluatedTemplateArr.push(getAttr(templateContext[refName], attrName));
25
+ evaluatedTemplateArr.push(getAttr((referenceRecord[refName] ?? endpointParams[refName]), attrName));
29
26
  }
30
27
  else {
31
- evaluatedTemplateArr.push(templateContext[parameterName]);
28
+ evaluatedTemplateArr.push((referenceRecord[parameterName] ?? endpointParams[parameterName]));
32
29
  }
33
30
  currentIndex = closingBraceIndex + 1;
34
31
  }
@@ -1,7 +1,3 @@
1
1
  export const getReferenceValue = ({ ref }, options) => {
2
- const referenceRecord = {
3
- ...options.endpointParams,
4
- ...options.referenceRecord,
5
- };
6
- return referenceRecord[ref];
2
+ return options.referenceRecord[ref] ?? options.endpointParams[ref];
7
3
  };
@@ -0,0 +1,22 @@
1
+ import type { EndpointObjectHeaders, ParameterObject } from "@smithy/types";
2
+ import type { FunctionArgv } from "../types/shared";
3
+ /**
4
+ * @internal
5
+ */
6
+ type BddCondition = [string, FunctionArgv] | [string, FunctionArgv, string];
7
+ /**
8
+ * @internal
9
+ */
10
+ type BddResult = [-1] | [-1, string] | [string, Record<string, ParameterObject>, EndpointObjectHeaders];
11
+ /**
12
+ * @internal
13
+ */
14
+ export declare class BinaryDecisionDiagram {
15
+ nodes: Int32Array;
16
+ root: number;
17
+ conditions: BddCondition[];
18
+ results: BddResult[];
19
+ private constructor();
20
+ static from(bdd: Int32Array, root: number, conditions: BddCondition[] | any[], results: BddResult[] | any[]): BinaryDecisionDiagram;
21
+ }
22
+ export {};
@@ -0,0 +1,7 @@
1
+ import type { EndpointV2 } from "@smithy/types";
2
+ import type { BinaryDecisionDiagram } from "./bdd/BinaryDecisionDiagram";
3
+ import type { EndpointResolverOptions } from "./types";
4
+ /**
5
+ * Resolves an endpoint URL by processing the endpoints bdd and options.
6
+ */
7
+ export declare const decideEndpoint: (bdd: BinaryDecisionDiagram, options: EndpointResolverOptions) => EndpointV2;
@@ -1,4 +1,6 @@
1
+ export { BinaryDecisionDiagram } from "./bdd/BinaryDecisionDiagram";
1
2
  export * from "./cache/EndpointCache";
3
+ export { decideEndpoint } from "./decideEndpoint";
2
4
  export * from "./lib/isIpAddress";
3
5
  export * from "./lib/isValidHostLabel";
4
6
  export * from "./utils/customEndpointFunctions";
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Evaluates arguments in order and returns the first non-empty result,
3
+ * otherwise returns the result of the last argument.
4
+ *
5
+ * @internal
6
+ */
7
+ export declare function coalesce<T>(...args: (T | undefined)[]): T | undefined;
@@ -1,9 +1,12 @@
1
1
  export * from "./booleanEquals";
2
+ export * from "./coalesce";
2
3
  export * from "./getAttr";
3
4
  export * from "./isSet";
4
5
  export * from "./isValidHostLabel";
6
+ export * from "./ite";
5
7
  export * from "./not";
6
8
  export * from "./parseURL";
9
+ export * from "./split";
7
10
  export * from "./stringEquals";
8
11
  export * from "./substring";
9
12
  export * from "./uriEncode";
@@ -0,0 +1,6 @@
1
+ /**
2
+ * An if-then-else function that returns one of two values based on a boolean condition.
3
+ *
4
+ * @internal
5
+ */
6
+ export declare function ite<T>(condition: boolean, trueValue: T | undefined, falseValue: T | undefined): T | undefined;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The split function divides a string into an array of substrings based on a non-empty delimiter.
3
+ * The behavior is controlled by the limit parameter:
4
+ *
5
+ * limit = 0: Split all occurrences (unlimited).
6
+ * limit = 1: No split performed (returns original string as single element array).
7
+ * limit > 1: Split into at most 'limit' parts (performs limit-1 splits).
8
+ *
9
+ * @internal
10
+ */
11
+ export declare function split(value: string, delimiter: string, limit: number): string[];
@@ -1,10 +1,14 @@
1
+ import { coalesce, ite, split } from "../lib";
1
2
  export declare const endpointFunctions: {
2
3
  booleanEquals: (value1: boolean, value2: boolean) => boolean;
4
+ coalesce: typeof coalesce;
3
5
  getAttr: (value: import("../lib").GetAttrValue, path: string) => import("../lib").GetAttrValue;
4
6
  isSet: (value: unknown) => value is {};
5
7
  isValidHostLabel: (value: string, allowSubDomains?: boolean) => boolean;
8
+ ite: typeof ite;
6
9
  not: (value: boolean) => boolean;
7
10
  parseURL: (value: string | URL | import("@smithy/types").Endpoint) => import("@smithy/types").EndpointURL | null;
11
+ split: typeof split;
8
12
  stringEquals: (value1: string, value2: string) => boolean;
9
13
  substring: (input: string, start: number, stop: number, reverse: boolean) => string | null;
10
14
  uriEncode: (value: string) => string;
@@ -1,2 +1,4 @@
1
1
  import type { EvaluateOptions, ReferenceObject } from "../types";
2
- export declare const getReferenceValue: ({ ref }: ReferenceObject, options: EvaluateOptions) => import("../types").FunctionReturn;
2
+ export declare const getReferenceValue: ({ ref }: ReferenceObject, options: EvaluateOptions) => string | number | boolean | import("@smithy/types").EndpointPartition | import("@smithy/types").EndpointARN | {
3
+ [key: string]: import("../types").FunctionReturn;
4
+ };
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smithy/util-endpoints",
3
- "version": "3.3.4",
3
+ "version": "3.4.0",
4
4
  "description": "Utilities to help with endpoint resolution.",
5
5
  "main": "./dist-cjs/index.js",
6
6
  "module": "./dist-es/index.js",