@saptools/service-flow 0.1.58 → 0.1.59

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.
@@ -2358,7 +2358,7 @@ function collectClassHelpers(sf) {
2358
2358
  // src/parsers/outbound-call-parser.ts
2359
2359
  import fs8 from "fs/promises";
2360
2360
  import path11 from "path";
2361
- import ts9 from "typescript";
2361
+ import ts10 from "typescript";
2362
2362
 
2363
2363
  // src/linker/external-http-target.ts
2364
2364
  import { createHash } from "crypto";
@@ -3080,6 +3080,8 @@ var capQueryBuilderRoots = /* @__PURE__ */ new Set([
3080
3080
  "SELECT.from",
3081
3081
  "SELECT.one.from",
3082
3082
  "SELECT.one",
3083
+ "SELECT.distinct.from",
3084
+ "SELECT.distinct.one.from",
3083
3085
  "INSERT.into",
3084
3086
  "UPSERT.into",
3085
3087
  "UPDATE.entity",
@@ -3280,20 +3282,15 @@ function nodeIsPromise(name) {
3280
3282
  return Boolean(name && ts8.isIdentifier(name) && name.text === "Promise");
3281
3283
  }
3282
3284
 
3283
- // src/parsers/outbound-call-parser.ts
3284
- function lineOf4(text, idx) {
3285
- return text.slice(0, idx).split("\n").length;
3286
- }
3287
- function entityFromExpression(expr) {
3288
- if (!expr) return void 0;
3289
- if (ts9.isIdentifier(expr) || ts9.isStringLiteral(expr) || ts9.isNoSubstitutionTemplateLiteral(expr)) return expr.text;
3290
- if (ts9.isPropertyAccessExpression(expr) && expr.expression.kind === ts9.SyntaxKind.ThisKeyword) return expr.name.text;
3291
- if (ts9.isElementAccessExpression(expr) && expr.argumentExpression && (ts9.isStringLiteral(expr.argumentExpression) || ts9.isNoSubstitutionTemplateLiteral(expr.argumentExpression))) return expr.argumentExpression.text;
3292
- return void 0;
3293
- }
3285
+ // src/parsers/001-query-entity-resolution.ts
3286
+ import ts9 from "typescript";
3287
+ var maxAliasDepth2 = 5;
3288
+ var cdsModelSpecifier = /^#cds-models(?:\/|$)/;
3289
+ var modelNamespaceCache = /* @__PURE__ */ new WeakMap();
3294
3290
  function expressionName2(expr) {
3295
3291
  if (ts9.isIdentifier(expr)) return expr.text;
3296
- if (ts9.isPropertyAccessExpression(expr)) return `${expressionName2(expr.expression)}.${expr.name.text}`;
3292
+ if (ts9.isPropertyAccessExpression(expr))
3293
+ return `${expressionName2(expr.expression)}.${expr.name.text}`;
3297
3294
  return expr.getText();
3298
3295
  }
3299
3296
  function variableInitializers(source) {
@@ -3301,7 +3298,8 @@ function variableInitializers(source) {
3301
3298
  for (const statement of source.statements) {
3302
3299
  if (!ts9.isVariableStatement(statement) || (statement.declarationList.flags & ts9.NodeFlags.Const) === 0) continue;
3303
3300
  for (const declaration of statement.declarationList.declarations) {
3304
- if (ts9.isIdentifier(declaration.name) && declaration.initializer) initializers.set(declaration.name.text, declaration.initializer);
3301
+ if (ts9.isIdentifier(declaration.name) && declaration.initializer)
3302
+ initializers.set(declaration.name.text, declaration.initializer);
3305
3303
  }
3306
3304
  }
3307
3305
  return initializers;
@@ -3311,18 +3309,349 @@ function unwrapQueryExpression2(expr) {
3311
3309
  return unwrapQueryExpression2(expr.expression);
3312
3310
  return expr;
3313
3311
  }
3314
- function queryEntityFromAst(expr, initializers = /* @__PURE__ */ new Map()) {
3315
- const unwrapped = unwrapQueryExpression2(expr);
3316
- if (ts9.isIdentifier(unwrapped) && initializers.has(unwrapped.text)) return queryEntityFromAst(initializers.get(unwrapped.text), initializers);
3317
- if (ts9.isCallExpression(unwrapped)) {
3318
- const name = expressionName2(unwrapped.expression);
3319
- if (name === "cds.run") return queryEntityFromAst(unwrapped.arguments[0], initializers);
3320
- if (isCapQueryBuilderRootName(name)) return entityFromExpression(unwrapped.arguments[0]);
3321
- const receiver = ts9.isPropertyAccessExpression(unwrapped.expression) ? unwrapped.expression.expression : void 0;
3322
- if (receiver) return queryEntityFromAst(receiver, initializers);
3312
+ function isFunctionLikeScope(node) {
3313
+ return ts9.isFunctionLike(node) || ts9.isSourceFile(node);
3314
+ }
3315
+ function nodeContains(parent, child) {
3316
+ const source = child.getSourceFile();
3317
+ return child.getStart(source) >= parent.getStart(source) && child.getEnd() <= parent.getEnd();
3318
+ }
3319
+ function isLoopInitializerScope(declaration, scope) {
3320
+ const list = declaration.parent;
3321
+ return ts9.isForStatement(scope) && scope.initializer === list || (ts9.isForInStatement(scope) || ts9.isForOfStatement(scope)) && scope.initializer === list;
3322
+ }
3323
+ function isLexicalScopeBoundary(node, declaration) {
3324
+ return ts9.isBlock(node) || ts9.isSourceFile(node) || ts9.isModuleBlock(node) || ts9.isCaseBlock(node) || isLoopInitializerScope(declaration, node) || isFunctionLikeScope(node);
3325
+ }
3326
+ function declarationScope2(node) {
3327
+ if (ts9.isParameter(node)) return node.parent;
3328
+ if (ts9.isCatchClause(node.parent) && node.parent.variableDeclaration === node)
3329
+ return node.parent;
3330
+ const list = node.parent;
3331
+ const blockScoped = (list.flags & (ts9.NodeFlags.Const | ts9.NodeFlags.Let)) !== 0;
3332
+ let current = list.parent;
3333
+ if (!blockScoped) {
3334
+ while (current.parent && !isFunctionLikeScope(current)) current = current.parent;
3335
+ return current;
3336
+ }
3337
+ while (current.parent && !isLexicalScopeBoundary(current, node))
3338
+ current = current.parent;
3339
+ return current;
3340
+ }
3341
+ function catchBindingScope(declaration) {
3342
+ if (ts9.isParameter(declaration)) return void 0;
3343
+ return ts9.isCatchClause(declaration.parent) && declaration.parent.variableDeclaration === declaration ? declaration.parent : void 0;
3344
+ }
3345
+ function declarationIsInScope(declaration, use) {
3346
+ const catchScope = catchBindingScope(declaration);
3347
+ if (catchScope) return nodeContains(catchScope.block, use);
3348
+ const scope = declarationScope2(declaration);
3349
+ if (ts9.isForStatement(scope) || ts9.isForInStatement(scope) || ts9.isForOfStatement(scope)) return nodeContains(scope.statement, use);
3350
+ return ts9.isSourceFile(scope) || nodeContains(scope, use);
3351
+ }
3352
+ function isAccessibleDeclaration(declaration, use) {
3353
+ return declaration.name.getStart(use.getSourceFile()) < use.getStart() && declarationIsInScope(declaration, use);
3354
+ }
3355
+ function resolveBinding2(identifier, use) {
3356
+ const source = use.getSourceFile();
3357
+ let best;
3358
+ const visit = (node) => {
3359
+ if (ts9.isVariableDeclaration(node) && ts9.isIdentifier(node.name) && node.name.text === identifier.text && isAccessibleDeclaration(node, use))
3360
+ best = node;
3361
+ if (ts9.isParameter(node) && ts9.isIdentifier(node.name) && node.name.text === identifier.text && isAccessibleDeclaration(node, use))
3362
+ best = node;
3363
+ ts9.forEachChild(node, visit);
3364
+ };
3365
+ visit(source);
3366
+ if (!best) return { immutable: false, evidence: ["binding_not_found"] };
3367
+ const immutable = ts9.isVariableDeclaration(best) && (best.parent.flags & ts9.NodeFlags.Const) !== 0;
3368
+ return {
3369
+ declaration: best,
3370
+ initializer: ts9.isVariableDeclaration(best) ? best.initializer : void 0,
3371
+ immutable,
3372
+ evidence: [immutable ? "lexical_const_binding_before_use" : "lexical_mutable_or_parameter_binding"]
3373
+ };
3374
+ }
3375
+ function directBindingElement(name, identifier) {
3376
+ if (ts9.isIdentifier(name)) return void 0;
3377
+ for (const element of name.elements) {
3378
+ if (ts9.isOmittedExpression(element) || element.dotDotDotToken || element.initializer || !ts9.isIdentifier(element.name)) continue;
3379
+ if (element.name.text === identifier.text) return element;
3323
3380
  }
3324
3381
  return void 0;
3325
3382
  }
3383
+ function bindingNameContains(name, target) {
3384
+ if (ts9.isIdentifier(name)) return name.text === target;
3385
+ return name.elements.some((element) => ts9.isBindingElement(element) && bindingNameContains(element.name, target));
3386
+ }
3387
+ function bindingScope(node) {
3388
+ if (ts9.isVariableDeclaration(node) || ts9.isParameter(node))
3389
+ return declarationScope2(node);
3390
+ if (ts9.isFunctionExpression(node) || ts9.isClassExpression(node)) return node;
3391
+ return node.parent;
3392
+ }
3393
+ function bindingIsCloser(candidate, current, use) {
3394
+ const source = use.getSourceFile();
3395
+ const candidateScope = bindingScope(candidate);
3396
+ const currentScope = bindingScope(current);
3397
+ const candidateSpan = candidateScope.getEnd() - candidateScope.getStart(source);
3398
+ const currentSpan = currentScope.getEnd() - currentScope.getStart(source);
3399
+ return candidateSpan < currentSpan || candidateSpan === currentSpan && candidate.getStart(source) > current.getStart(source);
3400
+ }
3401
+ function nearestScopedVariableDeclaration(identifier) {
3402
+ let best;
3403
+ const visit = (node) => {
3404
+ if ((ts9.isVariableDeclaration(node) || ts9.isParameter(node)) && bindingNameContains(node.name, identifier.text) && declarationIsInScope(node, identifier) && (!best || bindingIsCloser(node, best, identifier))) best = node;
3405
+ ts9.forEachChild(node, visit);
3406
+ };
3407
+ visit(identifier.getSourceFile());
3408
+ return best;
3409
+ }
3410
+ function hasScopedVariableDeclaration(identifier) {
3411
+ return Boolean(nearestScopedVariableDeclaration(identifier));
3412
+ }
3413
+ function namedValueDeclarationMatches(node, name) {
3414
+ if (ts9.isFunctionDeclaration(node) || ts9.isClassDeclaration(node) || ts9.isEnumDeclaration(node)) return node.name?.text === name;
3415
+ return ts9.isModuleDeclaration(node) && ts9.isIdentifier(node.name) && node.name.text === name;
3416
+ }
3417
+ function declarationContainerContains(node, use) {
3418
+ const container = node.parent;
3419
+ return ts9.isSourceFile(container) || (ts9.isBlock(container) || ts9.isModuleBlock(container)) && nodeContains(container, use);
3420
+ }
3421
+ function selfNamedValueDeclarationMatches(node, identifier) {
3422
+ return (ts9.isFunctionExpression(node) || ts9.isClassExpression(node)) && node.name?.text === identifier.text && nodeContains(node, identifier);
3423
+ }
3424
+ function scopedNonVariableDeclarationMatches(node, identifier) {
3425
+ return namedValueDeclarationMatches(node, identifier.text) && declarationContainerContains(node, identifier) || selfNamedValueDeclarationMatches(node, identifier);
3426
+ }
3427
+ function nearestScopedNonVariableDeclaration(identifier) {
3428
+ let best;
3429
+ const visit = (node) => {
3430
+ if (scopedNonVariableDeclarationMatches(node, identifier) && (!best || bindingIsCloser(node, best, identifier))) best = node;
3431
+ ts9.forEachChild(node, visit);
3432
+ };
3433
+ visit(identifier.getSourceFile());
3434
+ return best;
3435
+ }
3436
+ function hasScopedNonVariableDeclaration(identifier) {
3437
+ return Boolean(nearestScopedNonVariableDeclaration(identifier));
3438
+ }
3439
+ function nonVariableBindingWins(identifier, selected) {
3440
+ const declaration = nearestScopedNonVariableDeclaration(identifier);
3441
+ return Boolean(declaration && (!selected || bindingIsCloser(declaration, selected, identifier)));
3442
+ }
3443
+ function importClauseBinds(clause, name) {
3444
+ if (!clause || clause.isTypeOnly) return false;
3445
+ if (clause.name?.text === name) return true;
3446
+ const bindings = clause.namedBindings;
3447
+ if (!bindings) return false;
3448
+ if (ts9.isNamespaceImport(bindings)) return bindings.name.text === name;
3449
+ return bindings.elements.some((element) => !element.isTypeOnly && element.name.text === name);
3450
+ }
3451
+ function hasValueImportBinding(identifier) {
3452
+ return identifier.getSourceFile().statements.some((statement) => {
3453
+ if (ts9.isImportDeclaration(statement))
3454
+ return importClauseBinds(statement.importClause, identifier.text);
3455
+ return ts9.isImportEqualsDeclaration(statement) && !statement.isTypeOnly && statement.name.text === identifier.text;
3456
+ });
3457
+ }
3458
+ function sourcePropertyName(element, localName) {
3459
+ const property = element.propertyName;
3460
+ if (!property) return localName;
3461
+ if (ts9.isIdentifier(property) || ts9.isStringLiteral(property) || ts9.isNumericLiteral(property)) return property.text;
3462
+ return void 0;
3463
+ }
3464
+ function resolveDestructuredBinding(identifier, use) {
3465
+ const source = use.getSourceFile();
3466
+ let best;
3467
+ const visit = (node) => {
3468
+ if ((ts9.isVariableDeclaration(node) || ts9.isParameter(node)) && isAccessibleDeclaration(node, use)) {
3469
+ const element = directBindingElement(node.name, identifier);
3470
+ const entityName = element ? sourcePropertyName(element, identifier.text) : void 0;
3471
+ if (entityName && (!best || node.name.getStart(source) > best.declaration.name.getStart(source))) {
3472
+ best = {
3473
+ declaration: node,
3474
+ initializer: node.initializer,
3475
+ entityName
3476
+ };
3477
+ }
3478
+ }
3479
+ ts9.forEachChild(node, visit);
3480
+ };
3481
+ visit(source);
3482
+ return best;
3483
+ }
3484
+ function isEntitiesBase(expr) {
3485
+ const value = unwrapQueryExpression2(expr);
3486
+ if (ts9.isPropertyAccessExpression(value)) return value.name.text === "entities";
3487
+ return ts9.isCallExpression(value) && ts9.isPropertyAccessExpression(value.expression) && value.expression.name.text === "entities";
3488
+ }
3489
+ function hasLexicalValueShadow(identifier, includeImports) {
3490
+ return hasScopedVariableDeclaration(identifier) || hasScopedNonVariableDeclaration(identifier) || includeImports && hasValueImportBinding(identifier);
3491
+ }
3492
+ function modelRequire(expr) {
3493
+ const value = unwrapQueryExpression2(expr);
3494
+ if (!ts9.isCallExpression(value) || !ts9.isIdentifier(value.expression) || value.expression.text !== "require" || value.arguments.length !== 1)
3495
+ return false;
3496
+ if (hasLexicalValueShadow(value.expression, true)) return false;
3497
+ const specifier = value.arguments[0];
3498
+ return Boolean(specifier && ts9.isStringLiteralLike(specifier) && cdsModelSpecifier.test(specifier.text));
3499
+ }
3500
+ function modelNamespaceImportName(statement) {
3501
+ if (!ts9.isImportDeclaration(statement) || !ts9.isStringLiteralLike(statement.moduleSpecifier) || !cdsModelSpecifier.test(statement.moduleSpecifier.text) || statement.importClause?.isTypeOnly) return void 0;
3502
+ const bindings = statement.importClause?.namedBindings;
3503
+ return bindings && ts9.isNamespaceImport(bindings) ? bindings.name.text : void 0;
3504
+ }
3505
+ function modelImportEqualsName(statement) {
3506
+ if (!ts9.isImportEqualsDeclaration(statement) || statement.isTypeOnly || !ts9.isExternalModuleReference(statement.moduleReference)) return void 0;
3507
+ const specifier = statement.moduleReference.expression;
3508
+ return specifier && ts9.isStringLiteralLike(specifier) && cdsModelSpecifier.test(specifier.text) ? statement.name.text : void 0;
3509
+ }
3510
+ function modelNamespaceNames(source) {
3511
+ const cached = modelNamespaceCache.get(source);
3512
+ if (cached) return cached;
3513
+ const names = /* @__PURE__ */ new Set();
3514
+ for (const statement of source.statements) {
3515
+ const name = modelNamespaceImportName(statement) ?? modelImportEqualsName(statement);
3516
+ if (name) names.add(name);
3517
+ }
3518
+ modelNamespaceCache.set(source, names);
3519
+ return names;
3520
+ }
3521
+ function destructuredEntitySource(initializer) {
3522
+ if (!initializer) return false;
3523
+ if (isEntitiesBase(initializer) || modelRequire(initializer)) return true;
3524
+ const value = unwrapQueryExpression2(initializer);
3525
+ return ts9.isIdentifier(value) && !hasLexicalValueShadow(value, false) && modelNamespaceNames(value.getSourceFile()).has(value.text);
3526
+ }
3527
+ function isAssignmentOperator(kind) {
3528
+ return kind >= ts9.SyntaxKind.FirstAssignment && kind <= ts9.SyntaxKind.LastAssignment;
3529
+ }
3530
+ function identifierIsReadWithinTarget(identifier, parent) {
3531
+ if (ts9.isPropertyAccessExpression(parent) && parent.name === identifier) return true;
3532
+ if (ts9.isElementAccessExpression(parent) && parent.argumentExpression && nodeContains(parent.argumentExpression, identifier)) return true;
3533
+ if (ts9.isPropertyAssignment(parent) && nodeContains(parent.name, identifier)) return true;
3534
+ return ts9.isComputedPropertyName(parent) && nodeContains(parent.expression, identifier);
3535
+ }
3536
+ function identifierIsUnaryWrite(identifier) {
3537
+ const direct = identifier.parent;
3538
+ if (!((ts9.isPrefixUnaryExpression(direct) || ts9.isPostfixUnaryExpression(direct)) && direct.operand === identifier)) return false;
3539
+ return direct.operator === ts9.SyntaxKind.PlusPlusToken || direct.operator === ts9.SyntaxKind.MinusMinusToken;
3540
+ }
3541
+ function identifierIsNestedWrite(identifier) {
3542
+ let current = identifier;
3543
+ while (current.parent) {
3544
+ const parent = current.parent;
3545
+ if (identifierIsReadWithinTarget(identifier, parent)) return false;
3546
+ if (ts9.isBinaryExpression(parent))
3547
+ return isAssignmentOperator(parent.operatorToken.kind) && nodeContains(parent.left, identifier);
3548
+ if (ts9.isForInStatement(parent) || ts9.isForOfStatement(parent))
3549
+ return nodeContains(parent.initializer, identifier);
3550
+ current = parent;
3551
+ }
3552
+ return false;
3553
+ }
3554
+ function identifierIsWrite(identifier) {
3555
+ return identifierIsUnaryWrite(identifier) || identifierIsNestedWrite(identifier);
3556
+ }
3557
+ function destructuredBindingWasWritten(binding, localName, use) {
3558
+ if (ts9.isParameter(binding.declaration)) return true;
3559
+ if ((binding.declaration.parent.flags & ts9.NodeFlags.Const) !== 0) return false;
3560
+ let written = false;
3561
+ const declarationEnd = binding.declaration.name.getEnd();
3562
+ const useStart = use.getStart();
3563
+ const visit = (node) => {
3564
+ if (written) return;
3565
+ if (ts9.isIdentifier(node) && node.text === localName && node.getStart() > declarationEnd && node.getStart() < useStart && identifierIsWrite(node) && resolveDestructuredBinding(node, node)?.declaration === binding.declaration)
3566
+ written = true;
3567
+ ts9.forEachChild(node, visit);
3568
+ };
3569
+ visit(use.getSourceFile());
3570
+ return written;
3571
+ }
3572
+ function destructuredBindingWins(destructured, simple, use) {
3573
+ return !simple.declaration || bindingIsCloser(destructured.declaration, simple.declaration, use);
3574
+ }
3575
+ function entityFromDestructuredBinding(binding, identifier) {
3576
+ if (destructuredBindingWasWritten(binding, identifier.text, identifier))
3577
+ return void 0;
3578
+ return destructuredEntitySource(binding.initializer) ? binding.entityName : void 0;
3579
+ }
3580
+ function entityFromSimpleBinding(binding, depth, seen) {
3581
+ if (!binding.declaration || !binding.immutable || !binding.initializer || seen.has(binding.declaration)) return void 0;
3582
+ seen.add(binding.declaration);
3583
+ return entityFromExpression(binding.initializer, depth + 1, seen);
3584
+ }
3585
+ function scopedBindingIsCurrent(identifier, declaration) {
3586
+ return nearestScopedVariableDeclaration(identifier) === declaration && !nonVariableBindingWins(identifier, declaration);
3587
+ }
3588
+ function unboundEntityName(identifier) {
3589
+ return hasScopedVariableDeclaration(identifier) || hasScopedNonVariableDeclaration(identifier) ? void 0 : identifier.text;
3590
+ }
3591
+ function entityFromIdentifier(expr, depth, seen) {
3592
+ const binding = resolveBinding2(expr, expr);
3593
+ const destructured = resolveDestructuredBinding(expr, expr);
3594
+ if (destructured && destructuredBindingWins(destructured, binding, expr)) {
3595
+ return scopedBindingIsCurrent(expr, destructured.declaration) ? entityFromDestructuredBinding(destructured, expr) : void 0;
3596
+ }
3597
+ if (!binding.declaration) return unboundEntityName(expr);
3598
+ if (!scopedBindingIsCurrent(expr, binding.declaration)) return void 0;
3599
+ return entityFromSimpleBinding(binding, depth, seen);
3600
+ }
3601
+ function literalEntity(expr) {
3602
+ if (ts9.isStringLiteral(expr) || ts9.isNoSubstitutionTemplateLiteral(expr))
3603
+ return expr.text;
3604
+ if (!ts9.isElementAccessExpression(expr) || !expr.argumentExpression)
3605
+ return void 0;
3606
+ return ts9.isStringLiteral(expr.argumentExpression) || ts9.isNoSubstitutionTemplateLiteral(expr.argumentExpression) ? expr.argumentExpression.text : void 0;
3607
+ }
3608
+ function propertyEntity(expr) {
3609
+ if (!ts9.isPropertyAccessExpression(expr)) return void 0;
3610
+ if (expr.expression.kind === ts9.SyntaxKind.ThisKeyword) return void 0;
3611
+ return isEntitiesBase(expr.expression) ? expr.name.text : void 0;
3612
+ }
3613
+ function entityFromExpression(expr, depth = 0, seen = /* @__PURE__ */ new Set()) {
3614
+ if (!expr || depth >= maxAliasDepth2) return void 0;
3615
+ const value = unwrapQueryExpression2(expr);
3616
+ const literal2 = literalEntity(value);
3617
+ if (literal2 !== void 0) return literal2;
3618
+ if (ts9.isIdentifier(value)) return entityFromIdentifier(value, depth, seen);
3619
+ return propertyEntity(value);
3620
+ }
3621
+ function queryAliasInitializer(identifier, initializers, seen) {
3622
+ const initializer = initializers.get(identifier.text);
3623
+ if (!initializer || seen.has(identifier.text)) return void 0;
3624
+ const binding = resolveBinding2(identifier, identifier);
3625
+ if (!binding.declaration || !binding.immutable || binding.initializer !== initializer || nearestScopedVariableDeclaration(identifier) !== binding.declaration || nonVariableBindingWins(identifier, binding.declaration)) return void 0;
3626
+ seen.add(identifier.text);
3627
+ return initializer;
3628
+ }
3629
+ function queryEntityFromCall(call, initializers, seenInitializers) {
3630
+ const name = expressionName2(call.expression);
3631
+ if (name === "cds.run")
3632
+ return queryEntityFromAst(call.arguments[0], initializers, seenInitializers);
3633
+ if (isCapQueryBuilderRootName(name))
3634
+ return entityFromExpression(call.arguments[0]);
3635
+ const receiver = ts9.isPropertyAccessExpression(call.expression) ? call.expression.expression : void 0;
3636
+ return receiver ? queryEntityFromAst(receiver, initializers, seenInitializers) : void 0;
3637
+ }
3638
+ function queryEntityFromAst(expr, initializers = /* @__PURE__ */ new Map(), seenInitializers = /* @__PURE__ */ new Set()) {
3639
+ const unwrapped = unwrapQueryExpression2(expr);
3640
+ if (ts9.isIdentifier(unwrapped)) {
3641
+ const initializer = queryAliasInitializer(
3642
+ unwrapped,
3643
+ initializers,
3644
+ seenInitializers
3645
+ );
3646
+ return initializer ? queryEntityFromAst(initializer, initializers, seenInitializers) : void 0;
3647
+ }
3648
+ return ts9.isCallExpression(unwrapped) ? queryEntityFromCall(unwrapped, initializers, seenInitializers) : void 0;
3649
+ }
3650
+
3651
+ // src/parsers/outbound-call-parser.ts
3652
+ function lineOf4(text, idx) {
3653
+ return text.slice(0, idx).split("\n").length;
3654
+ }
3326
3655
  function queryBuilderEvidence(source, statement) {
3327
3656
  return {
3328
3657
  classifier: "cap_query_builder_direct",
@@ -3348,13 +3677,13 @@ function queryRunEvidence(source, argument) {
3348
3677
  };
3349
3678
  }
3350
3679
  function extractQueryEntity(expr) {
3351
- const source = ts9.createSourceFile("query.ts", `const __query = (${expr});`, ts9.ScriptTarget.Latest, true, ts9.ScriptKind.TS);
3680
+ const source = ts10.createSourceFile("query.ts", `const __query = (${expr});`, ts10.ScriptTarget.Latest, true, ts10.ScriptKind.TS);
3352
3681
  const initializers = variableInitializers(source);
3353
3682
  let found;
3354
3683
  const visit = (node) => {
3355
3684
  if (found) return;
3356
- if (ts9.isParenthesizedExpression(node)) found = queryEntityFromAst(node.expression, initializers);
3357
- ts9.forEachChild(node, visit);
3685
+ if (ts10.isParenthesizedExpression(node)) found = queryEntityFromAst(node.expression, initializers);
3686
+ ts10.forEachChild(node, visit);
3358
3687
  };
3359
3688
  visit(source);
3360
3689
  return found;
@@ -3368,7 +3697,7 @@ function parserEvidence(source, node, extra) {
3368
3697
  return { parser: "typescript_ast", startOffset: node.getStart(source), endOffset: node.getEnd(), ...extra };
3369
3698
  }
3370
3699
  function isStringLike(expr) {
3371
- return Boolean(expr && (ts9.isStringLiteral(expr) || ts9.isNoSubstitutionTemplateLiteral(expr)));
3700
+ return Boolean(expr && (ts10.isStringLiteral(expr) || ts10.isNoSubstitutionTemplateLiteral(expr)));
3372
3701
  }
3373
3702
  function literalText(expr) {
3374
3703
  if (isStringLike(expr)) return expr.text;
@@ -3376,86 +3705,35 @@ function literalText(expr) {
3376
3705
  }
3377
3706
  function objectPropertyText(object, key) {
3378
3707
  const prop = object.properties.find(
3379
- (property) => ts9.isPropertyAssignment(property) && nameOfProperty(property.name) === key || ts9.isShorthandPropertyAssignment(property) && property.name.text === key
3708
+ (property) => ts10.isPropertyAssignment(property) && nameOfProperty(property.name) === key || ts10.isShorthandPropertyAssignment(property) && property.name.text === key
3380
3709
  );
3381
3710
  if (!prop) return void 0;
3382
- return ts9.isShorthandPropertyAssignment(prop) ? prop.name.text : prop.initializer.getText();
3711
+ return ts10.isShorthandPropertyAssignment(prop) ? prop.name.text : prop.initializer.getText();
3383
3712
  }
3384
3713
  function objectPropertyIsShorthand(object, key) {
3385
- return object.properties.some((property) => ts9.isShorthandPropertyAssignment(property) && property.name.text === key);
3714
+ return object.properties.some((property) => ts10.isShorthandPropertyAssignment(property) && property.name.text === key);
3386
3715
  }
3387
3716
  function nameOfProperty(name) {
3388
- if (ts9.isIdentifier(name) || ts9.isStringLiteral(name) || ts9.isNumericLiteral(name)) return name.text;
3717
+ if (ts10.isIdentifier(name) || ts10.isStringLiteral(name) || ts10.isNumericLiteral(name)) return name.text;
3389
3718
  return void 0;
3390
3719
  }
3391
- var maxAliasDepth2 = 5;
3392
3720
  function safeRaw(expr) {
3393
- if (ts9.isStringLiteral(expr) || ts9.isNoSubstitutionTemplateLiteral(expr) || ts9.isIdentifier(expr) || ts9.isTemplateExpression(expr)) return expr.getText(expr.getSourceFile());
3721
+ if (ts10.isStringLiteral(expr) || ts10.isNoSubstitutionTemplateLiteral(expr) || ts10.isIdentifier(expr) || ts10.isTemplateExpression(expr)) return expr.getText(expr.getSourceFile());
3394
3722
  return void 0;
3395
3723
  }
3396
3724
  function placeholders2(expr) {
3397
3725
  return expr.templateSpans.map((span) => span.expression.getText(expr.getSourceFile()));
3398
3726
  }
3399
- function isFunctionLikeScope(node) {
3400
- return ts9.isFunctionLike(node) || ts9.isSourceFile(node);
3401
- }
3402
- function nodeContains(parent, child) {
3403
- const source = child.getSourceFile();
3404
- return child.getStart(source) >= parent.getStart(source) && child.getEnd() <= parent.getEnd();
3405
- }
3406
- function declarationScope2(node) {
3407
- if (ts9.isParameter(node)) return node.parent;
3408
- if (ts9.isCatchClause(node.parent) && node.parent.variableDeclaration === node) return node.parent;
3409
- const list = node.parent;
3410
- const blockScoped = (list.flags & (ts9.NodeFlags.Const | ts9.NodeFlags.Let)) !== 0;
3411
- let current = list.parent;
3412
- if (!blockScoped) {
3413
- while (current.parent && !isFunctionLikeScope(current)) current = current.parent;
3414
- return current;
3415
- }
3416
- while (current.parent && !ts9.isBlock(current) && !ts9.isSourceFile(current) && !ts9.isModuleBlock(current) && !ts9.isCaseBlock(current) && !isLoopInitializerScope(node, current) && !isFunctionLikeScope(current)) current = current.parent;
3417
- return current;
3418
- }
3419
- function isLoopInitializerScope(declaration, scope) {
3420
- const list = declaration.parent;
3421
- return ts9.isForStatement(scope) && scope.initializer === list || (ts9.isForInStatement(scope) || ts9.isForOfStatement(scope)) && scope.initializer === list;
3422
- }
3423
- function catchBindingScope(declaration) {
3424
- if (ts9.isParameter(declaration)) return void 0;
3425
- return ts9.isCatchClause(declaration.parent) && declaration.parent.variableDeclaration === declaration ? declaration.parent : void 0;
3426
- }
3427
- function isAccessibleDeclaration(declaration, use) {
3428
- const source = use.getSourceFile();
3429
- if (declaration.name.getStart(source) >= use.getStart(source)) return false;
3430
- const catchScope = catchBindingScope(declaration);
3431
- if (catchScope) return nodeContains(catchScope.block, use);
3432
- const scope = declarationScope2(declaration);
3433
- if (ts9.isForStatement(scope) || ts9.isForInStatement(scope) || ts9.isForOfStatement(scope)) return nodeContains(scope.statement, use);
3434
- return ts9.isSourceFile(scope) || nodeContains(scope, use);
3435
- }
3436
- function resolveBinding2(identifier, use) {
3437
- const source = use.getSourceFile();
3438
- let best;
3439
- const visit = (node) => {
3440
- if (ts9.isVariableDeclaration(node) && ts9.isIdentifier(node.name) && node.name.text === identifier.text && isAccessibleDeclaration(node, use)) best = node;
3441
- if (ts9.isParameter(node) && ts9.isIdentifier(node.name) && node.name.text === identifier.text && isAccessibleDeclaration(node, use)) best = node;
3442
- ts9.forEachChild(node, visit);
3443
- };
3444
- visit(source);
3445
- if (!best) return { immutable: false, evidence: ["binding_not_found"] };
3446
- const immutable = ts9.isVariableDeclaration(best) && (best.parent.flags & ts9.NodeFlags.Const) !== 0;
3447
- return { declaration: best, initializer: ts9.isVariableDeclaration(best) ? best.initializer : void 0, immutable, evidence: [immutable ? "lexical_const_binding_before_use" : "lexical_mutable_or_parameter_binding"] };
3448
- }
3449
3727
  function resolveExpression(expr, use, policy, depth = 0, seen = /* @__PURE__ */ new Set()) {
3450
3728
  if (!expr) return { status: "unknown", sourceKind: "dynamic_expression", placeholderKeys: [], evidence: ["expression_missing"] };
3451
- if (ts9.isStringLiteral(expr)) return { status: "static", sourceKind: "string_literal", value: expr.text, rawExpression: safeRaw(expr), placeholderKeys: [], evidence: ["string_literal"] };
3452
- if (ts9.isNoSubstitutionTemplateLiteral(expr)) return { status: "static", sourceKind: "no_substitution_template", value: expr.text, rawExpression: safeRaw(expr), placeholderKeys: [], evidence: ["no_substitution_template"] };
3453
- if (ts9.isTemplateExpression(expr)) {
3729
+ if (ts10.isStringLiteral(expr)) return { status: "static", sourceKind: "string_literal", value: expr.text, rawExpression: safeRaw(expr), placeholderKeys: [], evidence: ["string_literal"] };
3730
+ if (ts10.isNoSubstitutionTemplateLiteral(expr)) return { status: "static", sourceKind: "no_substitution_template", value: expr.text, rawExpression: safeRaw(expr), placeholderKeys: [], evidence: ["no_substitution_template"] };
3731
+ if (ts10.isTemplateExpression(expr)) {
3454
3732
  const keys = placeholders2(expr);
3455
3733
  if (policy === "operation_path") return { status: "dynamic", sourceKind: "template_with_substitutions", value: stripQuotes(expr.getText(expr.getSourceFile())), rawExpression: safeRaw(expr), placeholderKeys: keys, evidence: ["operation_path_template_placeholders_retained"] };
3456
3734
  return { status: "dynamic", sourceKind: "template_with_substitutions", placeholderKeys: keys, evidence: ["template_substitutions_not_static_external_target"] };
3457
3735
  }
3458
- if (ts9.isIdentifier(expr)) {
3736
+ if (ts10.isIdentifier(expr)) {
3459
3737
  if (depth >= maxAliasDepth2) return { status: "unknown", sourceKind: "const_alias", rawExpression: safeRaw(expr), placeholderKeys: [], evidence: ["alias_depth_exceeded"], constName: expr.text };
3460
3738
  const binding = resolveBinding2(expr, use);
3461
3739
  if (!binding.declaration || !binding.initializer || !binding.immutable) return { status: "dynamic", sourceKind: "dynamic_expression", rawExpression: safeRaw(expr), placeholderKeys: [], evidence: binding.evidence, constName: expr.text };
@@ -3464,12 +3742,12 @@ function resolveExpression(expr, use, policy, depth = 0, seen = /* @__PURE__ */
3464
3742
  const resolved3 = resolveExpression(binding.initializer, binding.declaration, policy, depth + 1, seen);
3465
3743
  return { ...resolved3, sourceKind: "const_alias", rawExpression: safeRaw(expr), constName: expr.text, evidence: [...binding.evidence, ...resolved3.evidence] };
3466
3744
  }
3467
- return { status: "dynamic", sourceKind: "dynamic_expression", rawExpression: safeRaw(expr), placeholderKeys: [], evidence: [`unsupported_${ts9.SyntaxKind[expr.kind] ?? "expression"}`] };
3745
+ return { status: "dynamic", sourceKind: "dynamic_expression", rawExpression: safeRaw(expr), placeholderKeys: [], evidence: [`unsupported_${ts10.SyntaxKind[expr.kind] ?? "expression"}`] };
3468
3746
  }
3469
3747
  function staticExpressionText(expr, initializers) {
3470
3748
  if (!expr) return void 0;
3471
3749
  if (isStringLike(expr)) return expr.text;
3472
- if (ts9.isIdentifier(expr) && initializers.has(expr.text)) return staticExpressionText(initializers.get(expr.text), initializers);
3750
+ if (ts10.isIdentifier(expr) && initializers.has(expr.text)) return staticExpressionText(initializers.get(expr.text), initializers);
3473
3751
  return void 0;
3474
3752
  }
3475
3753
  function operationPathFromStatic(text) {
@@ -3477,17 +3755,17 @@ function operationPathFromStatic(text) {
3477
3755
  }
3478
3756
  function destinationExpressionShape(expr) {
3479
3757
  if (!expr) return void 0;
3480
- if (ts9.isIdentifier(expr)) return "identifier";
3481
- if (ts9.isPropertyAccessExpression(expr) || ts9.isElementAccessExpression(expr)) return "property_read";
3482
- if (ts9.isCallExpression(expr)) return "function_call";
3483
- if (ts9.isConditionalExpression(expr)) return "conditional";
3484
- if (ts9.isBinaryExpression(expr)) return "binary_expression";
3485
- if (ts9.isTemplateExpression(expr)) return "template_expression";
3486
- return ts9.SyntaxKind[expr.kind] ?? "expression";
3758
+ if (ts10.isIdentifier(expr)) return "identifier";
3759
+ if (ts10.isPropertyAccessExpression(expr) || ts10.isElementAccessExpression(expr)) return "property_read";
3760
+ if (ts10.isCallExpression(expr)) return "function_call";
3761
+ if (ts10.isConditionalExpression(expr)) return "conditional";
3762
+ if (ts10.isBinaryExpression(expr)) return "binary_expression";
3763
+ if (ts10.isTemplateExpression(expr)) return "template_expression";
3764
+ return ts10.SyntaxKind[expr.kind] ?? "expression";
3487
3765
  }
3488
3766
  function staticConditionalCandidates(expr, initializers) {
3489
- const resolved3 = expr && ts9.isIdentifier(expr) && initializers.has(expr.text) ? initializers.get(expr.text) : expr;
3490
- if (!resolved3 || !ts9.isConditionalExpression(resolved3)) return void 0;
3767
+ const resolved3 = expr && ts10.isIdentifier(expr) && initializers.has(expr.text) ? initializers.get(expr.text) : expr;
3768
+ if (!resolved3 || !ts10.isConditionalExpression(resolved3)) return void 0;
3491
3769
  const left = staticExpressionText(resolved3.whenTrue, initializers);
3492
3770
  const right = staticExpressionText(resolved3.whenFalse, initializers);
3493
3771
  if (!left || !right) return void 0;
@@ -3495,8 +3773,8 @@ function staticConditionalCandidates(expr, initializers) {
3495
3773
  }
3496
3774
  function propertyInitializer(object, key) {
3497
3775
  for (const property of object.properties) {
3498
- if (ts9.isPropertyAssignment(property) && nameOfProperty(property.name) === key) return property.initializer;
3499
- if (ts9.isShorthandPropertyAssignment(property) && property.name.text === key) return property.name;
3776
+ if (ts10.isPropertyAssignment(property) && nameOfProperty(property.name) === key) return property.initializer;
3777
+ if (ts10.isShorthandPropertyAssignment(property) && property.name.text === key) return property.name;
3500
3778
  }
3501
3779
  return void 0;
3502
3780
  }
@@ -3557,7 +3835,7 @@ function externalHttpEvidence(node, source) {
3557
3835
  const exprText = expr.getText(source);
3558
3836
  if (exprText === "useOrFetchDestination") {
3559
3837
  const objectArg = node.arguments[0];
3560
- if (objectArg && ts9.isObjectLiteralExpression(objectArg)) {
3838
+ if (objectArg && ts10.isObjectLiteralExpression(objectArg)) {
3561
3839
  const destination = destinationTargetFromExpression(propertyInitializer(objectArg, "destinationName"), node);
3562
3840
  return { externalTarget: destination ?? { kind: "unknown", dynamic: false }, classifier: "sap_destination_lookup", sourceCallShape: "useOrFetchDestination" };
3563
3841
  }
@@ -3565,13 +3843,13 @@ function externalHttpEvidence(node, source) {
3565
3843
  if (exprText === "executeHttpRequest") {
3566
3844
  const destination = destinationTargetFromExpression(node.arguments[0], node);
3567
3845
  const config = node.arguments[1];
3568
- const method = config && ts9.isObjectLiteralExpression(config) ? httpMethodFromObject(config, node) : void 0;
3569
- const url = config && ts9.isObjectLiteralExpression(config) ? urlTargetFromExpression(propertyInitializer(config, "url"), node) : { kind: "unknown", dynamic: false };
3846
+ const method = config && ts10.isObjectLiteralExpression(config) ? httpMethodFromObject(config, node) : void 0;
3847
+ const url = config && ts10.isObjectLiteralExpression(config) ? urlTargetFromExpression(propertyInitializer(config, "url"), node) : { kind: "unknown", dynamic: false };
3570
3848
  return { method, externalTarget: destination ? { ...url, destination } : url, classifier: "sap_execute_http_request", sourceCallShape: "executeHttpRequest" };
3571
3849
  }
3572
3850
  if (exprText === "axios") {
3573
3851
  const config = node.arguments[0];
3574
- if (config && ts9.isObjectLiteralExpression(config)) {
3852
+ if (config && ts10.isObjectLiteralExpression(config)) {
3575
3853
  const method = httpMethodFromObject(config, node);
3576
3854
  return { method, externalTarget: urlTargetFromExpression(propertyInitializer(config, "url"), node), classifier: "axios_config_call", sourceCallShape: "axios(config)" };
3577
3855
  }
@@ -3579,10 +3857,10 @@ function externalHttpEvidence(node, source) {
3579
3857
  }
3580
3858
  if (exprText === "fetch") {
3581
3859
  const init = node.arguments[1];
3582
- const method = init && ts9.isObjectLiteralExpression(init) ? httpMethodFromObject(init, node) : void 0;
3860
+ const method = init && ts10.isObjectLiteralExpression(init) ? httpMethodFromObject(init, node) : void 0;
3583
3861
  return { method, externalTarget: urlTargetFromExpression(node.arguments[0], node), classifier: "fetch_call", sourceCallShape: "fetch" };
3584
3862
  }
3585
- if (ts9.isPropertyAccessExpression(expr) && ["get", "post", "put", "patch", "delete", "head"].includes(expr.name.text) && expr.expression.getText(source) === "axios") {
3863
+ if (ts10.isPropertyAccessExpression(expr) && ["get", "post", "put", "patch", "delete", "head"].includes(expr.name.text) && expr.expression.getText(source) === "axios") {
3586
3864
  return { method: expr.name.text.toUpperCase(), externalTarget: urlTargetFromExpression(node.arguments[0], node), classifier: "axios_member_call", sourceCallShape: `axios.${expr.name.text}` };
3587
3865
  }
3588
3866
  return void 0;
@@ -3590,27 +3868,27 @@ function externalHttpEvidence(node, source) {
3590
3868
  function collectServiceVariables(source) {
3591
3869
  const vars = /* @__PURE__ */ new Set(["cds", "messaging", "messageClient", "eventClient"]);
3592
3870
  const visit = (node) => {
3593
- if (ts9.isVariableDeclaration(node) && ts9.isIdentifier(node.name) && node.initializer) {
3871
+ if (ts10.isVariableDeclaration(node) && ts10.isIdentifier(node.name) && node.initializer) {
3594
3872
  const text = node.initializer.getText(source);
3595
3873
  if (/cds\.connect\.(to|messaging)\s*\(/.test(text)) vars.add(node.name.text);
3596
3874
  }
3597
- ts9.forEachChild(node, visit);
3875
+ ts10.forEachChild(node, visit);
3598
3876
  };
3599
3877
  visit(source);
3600
3878
  return vars;
3601
3879
  }
3602
3880
  function receiverName(expr) {
3603
- if (ts9.isIdentifier(expr)) return expr.text;
3604
- if (ts9.isPropertyAccessExpression(expr)) return expr.getText(sourceOf(expr));
3881
+ if (ts10.isIdentifier(expr)) return expr.text;
3882
+ if (ts10.isPropertyAccessExpression(expr)) return expr.getText(sourceOf(expr));
3605
3883
  return void 0;
3606
3884
  }
3607
3885
  function sourceOf(node) {
3608
3886
  return node.getSourceFile();
3609
3887
  }
3610
3888
  function rootReceiverName(expr) {
3611
- if (ts9.isIdentifier(expr)) return expr.text;
3612
- if (ts9.isPropertyAccessExpression(expr)) return rootReceiverName(expr.expression);
3613
- if (ts9.isCallExpression(expr)) return rootReceiverName(expr.expression);
3889
+ if (ts10.isIdentifier(expr)) return expr.text;
3890
+ if (ts10.isPropertyAccessExpression(expr)) return rootReceiverName(expr.expression);
3891
+ if (ts10.isCallExpression(expr)) return rootReceiverName(expr.expression);
3614
3892
  return void 0;
3615
3893
  }
3616
3894
  function isSupportedEventReceiver(receiver, rootReceiver, serviceVariables) {
@@ -3627,38 +3905,38 @@ function collectWrapperSpecs(source) {
3627
3905
  const serviceVariables = collectServiceVariables(source);
3628
3906
  const calledNames = /* @__PURE__ */ new Set();
3629
3907
  const collectCalls = (node) => {
3630
- if (ts9.isCallExpression(node) && ts9.isIdentifier(node.expression))
3908
+ if (ts10.isCallExpression(node) && ts10.isIdentifier(node.expression))
3631
3909
  calledNames.add(node.expression.text);
3632
- if (ts9.isCallExpression(node) && ts9.isCallExpression(node.expression) && ts9.isIdentifier(node.expression.expression))
3910
+ if (ts10.isCallExpression(node) && ts10.isCallExpression(node.expression) && ts10.isIdentifier(node.expression.expression))
3633
3911
  calledNames.add(node.expression.expression.text);
3634
- ts9.forEachChild(node, collectCalls);
3912
+ ts10.forEachChild(node, collectCalls);
3635
3913
  };
3636
3914
  collectCalls(source);
3637
3915
  const scanFunction = (name, fn) => {
3638
3916
  if (!calledNames.has(name) && !isExportedWrapper(fn)) return;
3639
- const params = fn.parameters.map((param) => ts9.isIdentifier(param.name) ? param.name.text : void 0);
3917
+ const params = fn.parameters.map((param) => ts10.isIdentifier(param.name) ? param.name.text : void 0);
3640
3918
  const sends = [];
3641
3919
  const visit = (node) => {
3642
- if (ts9.isCallExpression(node) && ts9.isPropertyAccessExpression(node.expression) && node.expression.name.text === "send" && ts9.isIdentifier(node.expression.expression)) {
3920
+ if (ts10.isCallExpression(node) && ts10.isPropertyAccessExpression(node.expression) && node.expression.name.text === "send" && ts10.isIdentifier(node.expression.expression)) {
3643
3921
  const objectArg = node.arguments[0];
3644
- if (objectArg && ts9.isObjectLiteralExpression(objectArg)) {
3922
+ if (objectArg && ts10.isObjectLiteralExpression(objectArg)) {
3645
3923
  const pathProp = propertyInitializer(objectArg, "path");
3646
3924
  const methodProp = propertyInitializer(objectArg, "method");
3647
- const pathName = pathProp && ts9.isIdentifier(pathProp) ? pathProp.text : void 0;
3648
- const methodName2 = methodProp && ts9.isIdentifier(methodProp) ? methodProp.text : void 0;
3925
+ const pathName = pathProp && ts10.isIdentifier(pathProp) ? pathProp.text : void 0;
3926
+ const methodName2 = methodProp && ts10.isIdentifier(methodProp) ? methodProp.text : void 0;
3649
3927
  const methodLiteral = resolveExpression(methodProp, node, "literal").value;
3650
3928
  if (pathName) sends.push({ client: node.expression.expression.text, path: pathName, method: methodName2, methodLiteral, start: node.getStart(source), end: node.getEnd() });
3651
3929
  }
3652
3930
  }
3653
- if (ts9.isCallExpression(node) && ts9.isIdentifier(node.expression) && specs.has(node.expression.text)) {
3931
+ if (ts10.isCallExpression(node) && ts10.isIdentifier(node.expression) && specs.has(node.expression.text)) {
3654
3932
  const nested = specs.get(node.expression.text);
3655
3933
  const pathArg = nested ? node.arguments[nested.pathIndex] : void 0;
3656
3934
  const clientArg = nested?.clientIndex === void 0 ? void 0 : node.arguments[nested.clientIndex];
3657
- const pathName = pathArg && ts9.isIdentifier(pathArg) ? pathArg.text : void 0;
3658
- const clientName = clientArg && ts9.isIdentifier(clientArg) ? clientArg.text : nested?.clientName;
3935
+ const pathName = pathArg && ts10.isIdentifier(pathArg) ? pathArg.text : void 0;
3936
+ const clientName = clientArg && ts10.isIdentifier(clientArg) ? clientArg.text : nested?.clientName;
3659
3937
  if (nested && pathName && clientName) sends.push({ client: clientName, path: pathName, method: nested.methodName, methodLiteral: nested.methodLiteral, nestedWrapperFunction: node.expression.text, start: node.getStart(source), end: node.getEnd() });
3660
3938
  }
3661
- ts9.forEachChild(node, visit);
3939
+ ts10.forEachChild(node, visit);
3662
3940
  };
3663
3941
  visit(fn);
3664
3942
  if (sends.length !== 1) return;
@@ -3670,17 +3948,17 @@ function collectWrapperSpecs(source) {
3670
3948
  if (pathIndex >= 0 && (clientIndex >= 0 || capturesKnownClient)) specs.set(name, { clientIndex: clientIndex >= 0 ? clientIndex : void 0, clientName: clientIndex >= 0 ? void 0 : found.client, pathIndex, methodIndex: methodIndex >= 0 ? methodIndex : void 0, methodName: found.method, methodLiteral: found.methodLiteral, nestedWrapperFunction: found.nestedWrapperFunction, definitionLine: lineOf4(source.text, fn.getStart(source)), internalStart: found.start, internalEnd: found.end });
3671
3949
  };
3672
3950
  const visitTop = (node) => {
3673
- if (ts9.isFunctionDeclaration(node) && node.name) scanFunction(node.name.text, node);
3674
- if (ts9.isVariableDeclaration(node) && ts9.isIdentifier(node.name) && node.initializer && (ts9.isArrowFunction(node.initializer) || ts9.isFunctionExpression(node.initializer))) scanFunction(node.name.text, node.initializer);
3675
- ts9.forEachChild(node, visitTop);
3951
+ if (ts10.isFunctionDeclaration(node) && node.name) scanFunction(node.name.text, node);
3952
+ if (ts10.isVariableDeclaration(node) && ts10.isIdentifier(node.name) && node.initializer && (ts10.isArrowFunction(node.initializer) || ts10.isFunctionExpression(node.initializer))) scanFunction(node.name.text, node.initializer);
3953
+ ts10.forEachChild(node, visitTop);
3676
3954
  };
3677
3955
  visitTop(source);
3678
3956
  return specs;
3679
3957
  }
3680
3958
  function isExportedWrapper(fn) {
3681
- const declaration = ts9.isFunctionDeclaration(fn) ? fn : ts9.isVariableDeclaration(fn.parent) ? fn.parent.parent.parent : void 0;
3682
- if (!declaration || !ts9.canHaveModifiers(declaration)) return false;
3683
- return ts9.getModifiers(declaration)?.some((modifier) => modifier.kind === ts9.SyntaxKind.ExportKeyword) ?? false;
3959
+ const declaration = ts10.isFunctionDeclaration(fn) ? fn : ts10.isVariableDeclaration(fn.parent) ? fn.parent.parent.parent : void 0;
3960
+ if (!declaration || !ts10.canHaveModifiers(declaration)) return false;
3961
+ return ts10.getModifiers(declaration)?.some((modifier) => modifier.kind === ts10.SyntaxKind.ExportKeyword) ?? false;
3684
3962
  }
3685
3963
  function classifyOutboundCallsInSource(source, filePath) {
3686
3964
  const calls = [];
@@ -3693,7 +3971,7 @@ function classifyOutboundCallsInSource(source, filePath) {
3693
3971
  calls.push({ node, fact: { ...fact, sourceFile, sourceLine: lineOf4(source.text, node.getStart(source)), confidence: fact.confidence ?? 0.8, evidence: parserEvidence(source, node, extra) } });
3694
3972
  };
3695
3973
  const visit = (node) => {
3696
- if (ts9.isCallExpression(node)) {
3974
+ if (ts10.isCallExpression(node)) {
3697
3975
  if (wrapperInternalRanges.some((range) => node.getStart(source) >= range.start && node.getEnd() <= range.end)) {
3698
3976
  return;
3699
3977
  }
@@ -3709,9 +3987,9 @@ function classifyOutboundCallsInSource(source, filePath) {
3709
3987
  const entity = queryEntityFromAst(directQuery.logicalCall, initializers);
3710
3988
  const payload = directQuery.logicalCall.getText(source);
3711
3989
  add(directQuery.logicalCall, { callType: "local_db_query", queryEntity: entity, payloadSummary: summarizeExpression(payload), confidence: entity ? 0.9 : 0.55, unresolvedReason: entity ? void 0 : queryWarning(payload) }, queryBuilderEvidence(source, directQuery));
3712
- } else if (ts9.isPropertyAccessExpression(expr) && expr.name.text === "send" && (ts9.isIdentifier(expr.expression) || ts9.isPropertyAccessExpression(expr.expression))) {
3990
+ } else if (ts10.isPropertyAccessExpression(expr) && expr.name.text === "send" && (ts10.isIdentifier(expr.expression) || ts10.isPropertyAccessExpression(expr.expression))) {
3713
3991
  const objectArg = node.arguments[0];
3714
- if (objectArg && ts9.isObjectLiteralExpression(objectArg)) {
3992
+ if (objectArg && ts10.isObjectLiteralExpression(objectArg)) {
3715
3993
  const receiver = receiverName(expr.expression);
3716
3994
  const query = objectPropertyText(objectArg, "query");
3717
3995
  const method = stripQuotes(resolveExpression(propertyInitializer(objectArg, "method"), node, "literal").value ?? objectPropertyText(objectArg, "method") ?? "POST");
@@ -3744,14 +4022,14 @@ function classifyOutboundCallsInSource(source, filePath) {
3744
4022
  add(node, { callType: "remote_action", serviceVariableName: rootReceiver ?? receiver, operationPathExpr, payloadSummary: summarizeExpression(node.getText(source)), confidence: operationPathExpr ? 0.75 : 0.35, unresolvedReason: operationPathExpr ? void 0 : "unsupported_cap_send_signature" }, { receiver, rootReceiver, classifier: operationPathExpr ? "service_client_send_operation_event" : "service_client_send_unsupported_signature", rawOperationExpression: firstArg2.rawExpression, literalOperationSource: firstArg2.value ? firstArg2.sourceKind : void 0, parserWarning: operationPathExpr ? void 0 : "unsupported_cap_send_signature" });
3745
4023
  }
3746
4024
  }
3747
- } else if (ts9.isCallExpression(expr) && ts9.isIdentifier(expr.expression) && wrapperSpecs.has(expr.expression.text) || ts9.isIdentifier(expr) && wrapperSpecs.has(expr.text)) {
3748
- const wrapperName = ts9.isIdentifier(expr) ? expr.text : ts9.isCallExpression(expr) && ts9.isIdentifier(expr.expression) ? expr.expression.text : "";
3749
- const wrapperArgs = ts9.isIdentifier(expr) ? node.arguments : ts9.isCallExpression(expr) ? expr.arguments : node.arguments;
4025
+ } else if (ts10.isCallExpression(expr) && ts10.isIdentifier(expr.expression) && wrapperSpecs.has(expr.expression.text) || ts10.isIdentifier(expr) && wrapperSpecs.has(expr.text)) {
4026
+ const wrapperName = ts10.isIdentifier(expr) ? expr.text : ts10.isCallExpression(expr) && ts10.isIdentifier(expr.expression) ? expr.expression.text : "";
4027
+ const wrapperArgs = ts10.isIdentifier(expr) ? node.arguments : ts10.isCallExpression(expr) ? expr.arguments : node.arguments;
3750
4028
  const spec = wrapperSpecs.get(wrapperName);
3751
4029
  const clientArg = spec?.clientIndex === void 0 ? void 0 : wrapperArgs[spec.clientIndex];
3752
4030
  const pathArg = spec ? wrapperArgs[spec.pathIndex] : void 0;
3753
4031
  const methodArg = spec?.methodIndex === void 0 ? void 0 : wrapperArgs[spec.methodIndex];
3754
- const receiver = clientArg && ts9.isIdentifier(clientArg) ? clientArg.text : spec?.clientName;
4032
+ const receiver = clientArg && ts10.isIdentifier(clientArg) ? clientArg.text : spec?.clientName;
3755
4033
  const method = stripQuotes(resolveExpression(methodArg, node, "literal").value ?? spec?.methodLiteral ?? "POST");
3756
4034
  const pathAnalysis = analyzeOperationPath(pathArg, node, method);
3757
4035
  const operationPathExpr = operationPathExpression(pathAnalysis);
@@ -3762,7 +4040,7 @@ function classifyOutboundCallsInSource(source, filePath) {
3762
4040
  } else if (spec && receiver) {
3763
4041
  add(node, { callType: "remote_action", serviceVariableName: receiver, method, payloadSummary: summarizeExpression(node.getText(source)), confidence: 0.45, unresolvedReason }, { receiver, classifier: pathAnalysis.status === "ambiguous" ? "higher_order_wrapper_ambiguous_path" : "higher_order_wrapper_dynamic_path", wrapperFunction: wrapperName, wrapperDefinitionLine: spec.definitionLine, callerLine: lineOf4(source.text, node.getStart(source)), wrapperPathSourceKind: wrapperSourceKind(pathAnalysis.sourceKind), rawPathExpression: pathAnalysis.rawExpression, pathAnalysis, parserWarning: unresolvedReason });
3764
4042
  }
3765
- } else if (ts9.isPropertyAccessExpression(expr) && ["emit", "publish", "on"].includes(expr.name.text)) {
4043
+ } else if (ts10.isPropertyAccessExpression(expr) && ["emit", "publish", "on"].includes(expr.name.text)) {
3766
4044
  const receiver = receiverName(expr.expression);
3767
4045
  const rootReceiver = rootReceiverName(expr.expression);
3768
4046
  if (isSupportedEventReceiver(receiver, rootReceiver, serviceVariables)) {
@@ -3778,7 +4056,7 @@ function classifyOutboundCallsInSource(source, filePath) {
3778
4056
  }
3779
4057
  }
3780
4058
  }
3781
- ts9.forEachChild(node, visit);
4059
+ ts10.forEachChild(node, visit);
3782
4060
  };
3783
4061
  visit(source);
3784
4062
  return calls;
@@ -3792,12 +4070,12 @@ function containsSupportedOutboundCall(node) {
3792
4070
  async function parseOutboundCalls(repoPath, filePath, context) {
3793
4071
  const snapshot = context?.get(filePath);
3794
4072
  const text = snapshot?.text ?? await fs8.readFile(path11.join(repoPath, filePath), "utf8");
3795
- const source = snapshot?.sourceFile() ?? ts9.createSourceFile(
4073
+ const source = snapshot?.sourceFile() ?? ts10.createSourceFile(
3796
4074
  filePath,
3797
4075
  text,
3798
- ts9.ScriptTarget.Latest,
4076
+ ts10.ScriptTarget.Latest,
3799
4077
  true,
3800
- filePath.endsWith(".ts") ? ts9.ScriptKind.TS : ts9.ScriptKind.JS
4078
+ filePath.endsWith(".ts") ? ts10.ScriptKind.TS : ts10.ScriptKind.JS
3801
4079
  );
3802
4080
  const bindingNames = new Set((await parseServiceBindings(
3803
4081
  repoPath,
@@ -3813,21 +4091,21 @@ async function parseOutboundCalls(repoPath, filePath, context) {
3813
4091
  );
3814
4092
  return [...classifyOutboundCallsInSource(source, filePath).map((call) => call.fact), ...importedWrappers, ...parseLocalServiceCalls(text, filePath, source)];
3815
4093
  }
3816
- function parseLocalServiceCalls(text, filePath, source = ts9.createSourceFile(
4094
+ function parseLocalServiceCalls(text, filePath, source = ts10.createSourceFile(
3817
4095
  filePath,
3818
4096
  text,
3819
- ts9.ScriptTarget.Latest,
4097
+ ts10.ScriptTarget.Latest,
3820
4098
  true,
3821
- filePath.endsWith(".ts") ? ts9.ScriptKind.TS : ts9.ScriptKind.JS
4099
+ filePath.endsWith(".ts") ? ts10.ScriptKind.TS : ts10.ScriptKind.JS
3822
4100
  )) {
3823
4101
  const aliases = /* @__PURE__ */ new Map();
3824
4102
  const calls = [];
3825
4103
  const visit = (node) => {
3826
- if (ts9.isVariableDeclaration(node) && ts9.isIdentifier(node.name) && node.initializer) {
4104
+ if (ts10.isVariableDeclaration(node) && ts10.isIdentifier(node.name) && node.initializer) {
3827
4105
  const origin = serviceLookup(node.initializer, aliases);
3828
4106
  if (origin) aliases.set(node.name.text, { ...origin, chain: [...origin.chain, node.name.text] });
3829
4107
  }
3830
- if (ts9.isCallExpression(node)) {
4108
+ if (ts10.isCallExpression(node)) {
3831
4109
  const parsed = serviceOperationCall(node, aliases);
3832
4110
  if (parsed && parsed.operation !== "entities") calls.push({
3833
4111
  callType: "local_service_call",
@@ -3850,20 +4128,20 @@ function parseLocalServiceCalls(text, filePath, source = ts9.createSourceFile(
3850
4128
  })
3851
4129
  });
3852
4130
  }
3853
- ts9.forEachChild(node, visit);
4131
+ ts10.forEachChild(node, visit);
3854
4132
  };
3855
4133
  visit(source);
3856
4134
  return calls;
3857
4135
  }
3858
4136
  function serviceLookup(expr, aliases) {
3859
- if (ts9.isIdentifier(expr)) return aliases.get(expr.text);
3860
- if (ts9.isPropertyAccessExpression(expr) && expr.expression.getText() === "cds.services") return { service: expr.name.text, lookup: expr.getText(), chain: [expr.getText()] };
3861
- if (ts9.isElementAccessExpression(expr) && expr.expression.getText() === "cds.services" && ts9.isStringLiteral(expr.argumentExpression)) return { service: expr.argumentExpression.text, lookup: expr.getText(), chain: [expr.getText()] };
4137
+ if (ts10.isIdentifier(expr)) return aliases.get(expr.text);
4138
+ if (ts10.isPropertyAccessExpression(expr) && expr.expression.getText() === "cds.services") return { service: expr.name.text, lookup: expr.getText(), chain: [expr.getText()] };
4139
+ if (ts10.isElementAccessExpression(expr) && expr.expression.getText() === "cds.services" && ts10.isStringLiteral(expr.argumentExpression)) return { service: expr.argumentExpression.text, lookup: expr.getText(), chain: [expr.getText()] };
3862
4140
  return void 0;
3863
4141
  }
3864
4142
  function serviceOperationCall(node, aliases) {
3865
4143
  const expr = node.expression;
3866
- if (!ts9.isPropertyAccessExpression(expr)) return void 0;
4144
+ if (!ts10.isPropertyAccessExpression(expr)) return void 0;
3867
4145
  const origin = serviceLookup(expr.expression, aliases);
3868
4146
  if (!origin) return void 0;
3869
4147
  if (expr.name.text === "send") {
@@ -8692,4 +8970,4 @@ export {
8692
8970
  selectorRepoAmbiguousDiagnostic,
8693
8971
  trace
8694
8972
  };
8695
- //# sourceMappingURL=chunk-CRSSXWQ2.js.map
8973
+ //# sourceMappingURL=chunk-GLZSDBRG.js.map