@saptools/service-flow 0.1.63 → 0.1.64

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.
@@ -1637,11 +1637,40 @@ function readExports(repoPath, filePath, seen, context) {
1637
1637
 
1638
1638
  // src/utils/redaction.ts
1639
1639
  var SENSITIVE = /authorization|cookie|token|secret|password|key|credential/i;
1640
+ var SENSITIVE_KEYWORD = /authorization|cookie|token|secret|password|key|credential/gi;
1641
+ function isWhitespace(value) {
1642
+ return value !== void 0 && /\s/u.test(value);
1643
+ }
1644
+ function redactionSpan(text, start, keyword) {
1645
+ let cursor = start + keyword.length;
1646
+ while (isWhitespace(text[cursor])) cursor += 1;
1647
+ if (text[cursor] !== ":" && text[cursor] !== "=") return void 0;
1648
+ cursor += 1;
1649
+ while (isWhitespace(text[cursor])) cursor += 1;
1650
+ const candidateQuote = text[cursor];
1651
+ const quote = candidateQuote === "'" || candidateQuote === '"' || candidateQuote === "`" ? candidateQuote : void 0;
1652
+ if (quote !== void 0) cursor += 1;
1653
+ const valueStart = cursor;
1654
+ while (cursor < text.length && !/[,'"`}\s]/u.test(text[cursor] ?? "")) cursor += 1;
1655
+ if (cursor === valueStart) return void 0;
1656
+ if (quote !== void 0) {
1657
+ if (text[cursor] !== quote) return void 0;
1658
+ cursor += 1;
1659
+ }
1660
+ return { start, end: cursor, keyword };
1661
+ }
1640
1662
  function redactText(text) {
1641
- return text.replace(
1642
- /(authorization|cookie|token|secret|password|key|credential)\s*[:=]\s*(['"`]?)[^,'"`}\s]+\2/gi,
1643
- "$1: [REDACTED]"
1644
- );
1663
+ let cursor = 0;
1664
+ let output = "";
1665
+ for (const match of text.matchAll(SENSITIVE_KEYWORD)) {
1666
+ const start = match.index ?? 0;
1667
+ if (start < cursor) continue;
1668
+ const span = redactionSpan(text, start, match[0]);
1669
+ if (span === void 0) continue;
1670
+ output += text.slice(cursor, span.start) + `${span.keyword}: [REDACTED]`;
1671
+ cursor = span.end;
1672
+ }
1673
+ return output + text.slice(cursor);
1645
1674
  }
1646
1675
  function redactValue(value) {
1647
1676
  if (Array.isArray(value)) return value.map(redactValue);
@@ -1665,6 +1694,31 @@ import ts5 from "typescript";
1665
1694
  import fs7 from "fs/promises";
1666
1695
  import path8 from "path";
1667
1696
  import ts4 from "typescript";
1697
+
1698
+ // src/utils/001-placeholders.ts
1699
+ function scanPlaceholders(value) {
1700
+ const input = value ?? "";
1701
+ const spans = [];
1702
+ let cursor = 0;
1703
+ while (cursor < input.length) {
1704
+ const start = input.indexOf("${", cursor);
1705
+ if (start < 0) break;
1706
+ const closingBrace = input.indexOf("}", start + 2);
1707
+ if (closingBrace < 0) break;
1708
+ spans.push({
1709
+ start,
1710
+ end: closingBrace + 1,
1711
+ key: input.slice(start + 2, closingBrace)
1712
+ });
1713
+ cursor = closingBrace + 1;
1714
+ }
1715
+ return spans;
1716
+ }
1717
+ function extractPlaceholderKeys(value) {
1718
+ return scanPlaceholders(value).map((span) => span.key.trim()).filter(Boolean);
1719
+ }
1720
+
1721
+ // src/parsers/service-binding-parser-helpers.ts
1668
1722
  function lineOf3(sf, node) {
1669
1723
  return sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
1670
1724
  }
@@ -1675,7 +1729,7 @@ function stringValue2(node) {
1675
1729
  return node.getText();
1676
1730
  }
1677
1731
  function placeholders(value) {
1678
- return [...(value ?? "").matchAll(/\$\{([^}]*)\}/g)].map((m) => (m[1] ?? "").trim()).filter(Boolean);
1732
+ return extractPlaceholderKeys(value);
1679
1733
  }
1680
1734
  function connectFactFromCall(call) {
1681
1735
  const expr = call.expression;
@@ -4152,12 +4206,11 @@ function serviceOperationCall(node, aliases) {
4152
4206
  }
4153
4207
 
4154
4208
  // src/linker/dynamic-edge-resolver.ts
4155
- var PLACEHOLDER = /\$\{([^}]*)\}/g;
4156
4209
  function applyVariables(template, vars) {
4157
4210
  return substituteVariables(template, vars).effective;
4158
4211
  }
4159
4212
  function extractPlaceholders(template) {
4160
- return [...(template ?? "").matchAll(PLACEHOLDER)].map((m) => (m[1] ?? "").trim()).filter(Boolean);
4213
+ return extractPlaceholderKeys(template);
4161
4214
  }
4162
4215
  function matchRuntimeTemplate(template, concrete) {
4163
4216
  if (!template || !concrete) return void 0;
@@ -4180,10 +4233,15 @@ function substituteVariables(template, vars) {
4180
4233
  const placeholders3 = [...new Set(extractPlaceholders(template))];
4181
4234
  const supplied = placeholders3.filter((key) => Object.hasOwn(vars, key));
4182
4235
  const missing = placeholders3.filter((key) => !Object.hasOwn(vars, key));
4183
- const effective = template.replace(PLACEHOLDER, (_m, key) => {
4184
- const trimmed = key.trim();
4185
- return Object.hasOwn(vars, trimmed) ? vars[trimmed] ?? "" : `\${${trimmed}}`;
4186
- });
4236
+ let lastIndex = 0;
4237
+ let effective = "";
4238
+ for (const span of scanPlaceholders(template)) {
4239
+ const trimmed = span.key.trim();
4240
+ const replacement = Object.hasOwn(vars, trimmed) ? vars[trimmed] ?? "" : `\${${trimmed}}`;
4241
+ effective += template.slice(lastIndex, span.start) + replacement;
4242
+ lastIndex = span.end;
4243
+ }
4244
+ effective += template.slice(lastIndex);
4187
4245
  return {
4188
4246
  original: template,
4189
4247
  effective,
@@ -4196,10 +4254,10 @@ function substituteVariables(template, vars) {
4196
4254
  function runtimeTemplatePattern(template) {
4197
4255
  let pattern = "";
4198
4256
  let lastIndex = 0;
4199
- for (const match of template.matchAll(PLACEHOLDER)) {
4200
- pattern += escapeRegex(template.slice(lastIndex, match.index));
4257
+ for (const span of scanPlaceholders(template)) {
4258
+ pattern += escapeRegex(template.slice(lastIndex, span.start));
4201
4259
  pattern += "([^/]+?)";
4202
- lastIndex = (match.index ?? 0) + match[0].length;
4260
+ lastIndex = span.end;
4203
4261
  }
4204
4262
  return `${pattern}${escapeRegex(template.slice(lastIndex))}`;
4205
4263
  }
@@ -5187,7 +5245,7 @@ function operationMatches(candidate, operationPath) {
5187
5245
  return candidate.operationPath === names.path || candidate.operationPath === names.simplePath || candidate.operationName === names.name || candidate.operationName === names.simpleName;
5188
5246
  }
5189
5247
  function resolveOperation(db, signals, workspaceId) {
5190
- const missing = [signals.servicePath, signals.alias, signals.destination, signals.operationPath].flatMap((value) => [...(value ?? "").matchAll(/\$\{([^}]*)\}/g)].map((match) => (match[1] ?? "").trim())).filter(Boolean);
5248
+ const missing = [signals.servicePath, signals.alias, signals.destination, signals.operationPath].flatMap(extractPlaceholderKeys);
5191
5249
  if (missing.length > 0)
5192
5250
  return {
5193
5251
  status: "dynamic",
@@ -5533,7 +5591,7 @@ function compactCandidateScores(candidates2) {
5533
5591
  }));
5534
5592
  }
5535
5593
  function placeholderKeys(values) {
5536
- const keys = values.flatMap((value) => [...(value ?? "").matchAll(/\$\{([^}]*)\}/g)].map((match) => (match[1] ?? "").trim()).filter(Boolean));
5594
+ const keys = values.flatMap(extractPlaceholderKeys);
5537
5595
  return [...new Set(keys)].sort();
5538
5596
  }
5539
5597
  function parseJson(value) {
@@ -5811,7 +5869,7 @@ function insertCallEdge(db, workspaceId, call, vars, generation) {
5811
5869
  }
5812
5870
  if (isRemoteEntityCall) {
5813
5871
  const target = buildRemoteQueryTarget({ queryEntity: intent.entitySegment ?? call.query_entity, servicePath, serviceAlias: call.alias, serviceAliasExpr: call.aliasExpr, destination: destination ? applyVariables(destination, vars) : void 0, isDynamic, parserWarning: evidence.parserWarning });
5814
- const entityKind = callType.replace("remote_entity_", "remote_entity_");
5872
+ const entityKind = callType;
5815
5873
  db.prepare("INSERT INTO graph_edges(workspace_id,edge_type,status,from_kind,from_id,to_kind,to_id,confidence,evidence_json,is_dynamic,generation) VALUES(?,?,?,?,?,?,?,?,?,?,?)").run(workspaceId, "HANDLER_ACCESSES_REMOTE_ENTITY", "terminal", "call", String(call.id), target.toKind, target.toId, Number(call.confidence ?? 0.5), JSON.stringify({ ...evidence, ...target.evidence, remoteEntityAccess: entityKind }), 0, generation);
5816
5874
  return { status: "terminal", callType };
5817
5875
  }
@@ -6515,17 +6573,18 @@ function proposalForIdentity(candidate, template, identity, sourceKind, npmPacka
6515
6573
  }];
6516
6574
  }
6517
6575
  function matchIdentityTemplate(template, identity, npmPackage) {
6518
- const matches2 = [...template.matchAll(/\$\{([^}]*)\}/g)];
6519
- if (matches2.length !== 1 || !matches2[0]?.[1]) return void 0;
6520
- const placeholder = matches2[0][0];
6521
- const sentinel = "dynamicplaceholdertoken";
6576
+ const matches2 = scanPlaceholders(template);
6577
+ const matchSpan = matches2[0];
6578
+ if (matches2.length !== 1 || !matchSpan?.key) return void 0;
6579
+ const placeholder = template.slice(matchSpan.start, matchSpan.end);
6580
+ const sentinel = "dynamic_placeholder_token";
6522
6581
  const normalizedTemplate = normalizeIdentity(template.replace(placeholder, sentinel));
6523
6582
  const [prefix, suffix, extra] = normalizedTemplate.split(sentinel);
6524
6583
  if (!prefix || !suffix || extra !== void 0) return void 0;
6525
6584
  const normalizedIdentity = normalizeIdentity(identity, npmPackage);
6526
6585
  const match = new RegExp(`^${escapeRegex2(prefix)}([a-z0-9]+)${escapeRegex2(suffix)}$`).exec(normalizedIdentity);
6527
6586
  if (!match?.[1]) return void 0;
6528
- return { key: matches2[0][1].trim(), value: match[1], normalizedIdentity };
6587
+ return { key: matchSpan.key.trim(), value: match[1], normalizedIdentity };
6529
6588
  }
6530
6589
  function competingIdentityKeys(proposals) {
6531
6590
  const owners = /* @__PURE__ */ new Map();
@@ -6630,7 +6689,7 @@ function routeImplementationEvidence(db, operationId) {
6630
6689
  }
6631
6690
  function normalizeIdentity(value, npmPackage = false) {
6632
6691
  const unscoped = npmPackage && /^@[^/]+\/[^/]+$/.test(value) ? value.slice(value.indexOf("/") + 1) : value;
6633
- return unscoped.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
6692
+ return unscoped.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|(?<!_)_+$/g, "");
6634
6693
  }
6635
6694
  function stringValue7(value) {
6636
6695
  return typeof value === "string" ? value : void 0;
@@ -8967,4 +9026,4 @@ export {
8967
9026
  selectorRepoAmbiguousDiagnostic,
8968
9027
  trace
8969
9028
  };
8970
- //# sourceMappingURL=chunk-EGBTHN7J.js.map
9029
+ //# sourceMappingURL=chunk-TBH33OYC.js.map