/**
 * This file is part of the NocoBase (R) project.
 * Copyright (c) 2020-2024 NocoBase Co., Ltd.
 * Authors: NocoBase Team.
 *
 * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
 * For more information, please refer to: https://www.nocobase.com/agreement.
 */

var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var ctx_api_exports = {};
__export(ctx_api_exports, {
  buildInvalidCtxApiMemberAccess: () => buildInvalidCtxApiMemberAccess,
  buildInvalidCtxLibMemberAccess: () => buildInvalidCtxLibMemberAccess,
  collectAstInvalidApiResourceCall: () => collectAstInvalidApiResourceCall,
  collectAstInvalidCtxApiMemberAccess: () => collectAstInvalidCtxApiMemberAccess,
  collectAstInvalidCtxApiPatternAccesses: () => collectAstInvalidCtxApiPatternAccesses,
  collectAstInvalidCtxApiReadonlyWrites: () => collectAstInvalidCtxApiReadonlyWrites,
  collectAstInvalidCtxLibMemberAccess: () => collectAstInvalidCtxLibMemberAccess,
  collectAstInvalidCtxLibPatternAccesses: () => collectAstInvalidCtxLibPatternAccesses,
  collectAstInvalidCtxNonFunctionCall: () => collectAstInvalidCtxNonFunctionCall,
  collectAstWriteTargetNodes: () => collectAstWriteTargetNodes,
  collectCtxApiAliasesFromAst: () => collectCtxApiAliasesFromAst,
  collectCtxApiObjectPatternAliases: () => collectCtxApiObjectPatternAliases,
  collectCtxApiResourceAliasesFromAst: () => collectCtxApiResourceAliasesFromAst,
  collectCtxDefiniteRootAliasesFromAst: () => collectCtxDefiniteRootAliasesFromAst,
  collectCtxLibAliasesFromAst: () => collectCtxLibAliasesFromAst,
  collectCtxLibObjectPatternAliases: () => collectCtxLibObjectPatternAliases,
  collectCtxLibsRootAliasesFromAst: () => collectCtxLibsRootAliasesFromAst,
  collectCtxMethodAliasesFromAst: () => collectCtxMethodAliasesFromAst,
  collectCtxNonFunctionRootAliasesFromAst: () => collectCtxNonFunctionRootAliasesFromAst,
  collectCtxRootAliasesFromAst: () => collectCtxRootAliasesFromAst,
  collectInvalidCtxApiObjectPatternAccesses: () => collectInvalidCtxApiObjectPatternAccesses,
  collectInvalidCtxLibObjectPatternAccesses: () => collectInvalidCtxLibObjectPatternAccesses,
  collectMaybeCtxApiResourceCallsFromAst: () => collectMaybeCtxApiResourceCallsFromAst,
  collectMaybeCtxApiResourceHandleAliasesFromAst: () => collectMaybeCtxApiResourceHandleAliasesFromAst,
  collectPossibleCtxApiCapabilitiesFromAst: () => collectPossibleCtxApiCapabilitiesFromAst,
  filterInvalidCtxApiMemberAccessesForResourceCalls: () => filterInvalidCtxApiMemberAccessesForResourceCalls,
  getCtxApiAliasMemberPath: () => getCtxApiAliasMemberPath,
  getCtxApiCapabilityFromAst: () => getCtxApiCapabilityFromAst,
  getCtxApiCapabilityMemberPath: () => getCtxApiCapabilityMemberPath,
  getCtxApiCapabilityMemberPrefix: () => getCtxApiCapabilityMemberPrefix,
  getCtxApiMemberAccessFromAst: () => getCtxApiMemberAccessFromAst,
  getCtxApiMemberPathFromAst: () => getCtxApiMemberPathFromAst,
  getCtxApiResourceCallFromAst: () => getCtxApiResourceCallFromAst,
  getCtxApiResourceCallIdentity: () => getCtxApiResourceCallIdentity,
  getCtxApiResourceCalleeFromAst: () => getCtxApiResourceCalleeFromAst,
  getCtxApiResourceChainedMethodFromAst: () => getCtxApiResourceChainedMethodFromAst,
  getCtxApiResourceHandleAliasFromAst: () => getCtxApiResourceHandleAliasFromAst,
  getCtxApiResourceHandleAliasIdentity: () => getCtxApiResourceHandleAliasIdentity,
  getCtxApiResourceMethodAliasFromAst: () => getCtxApiResourceMethodAliasFromAst,
  getCtxLibMemberCapability: () => getCtxLibMemberCapability,
  getCtxLibMemberPathFromAst: () => getCtxLibMemberPathFromAst,
  getDirectCtxLibPathFromAst: () => getDirectCtxLibPathFromAst,
  getMaybeCtxApiCapabilityFromAst: () => getMaybeCtxApiCapabilityFromAst,
  getMaybeCtxApiResourceCallFromAst: () => getMaybeCtxApiResourceCallFromAst,
  getMaybeCtxApiResourceHandleAliasFromAst: () => getMaybeCtxApiResourceHandleAliasFromAst,
  getMaybeCtxApiResourceMethodAliasFromAst: () => getMaybeCtxApiResourceMethodAliasFromAst,
  getSuggestedCtxLibMemberImport: () => getSuggestedCtxLibMemberImport,
  getUniqueCtxApiResourceCall: () => getUniqueCtxApiResourceCall,
  getUniqueCtxApiResourceHandleAlias: () => getUniqueCtxApiResourceHandleAlias,
  getWrappedCtxApiResourceChainedMethodFromAst: () => getWrappedCtxApiResourceChainedMethodFromAst,
  isCtxApiCapabilityDefinitelyTruthy: () => isCtxApiCapabilityDefinitelyTruthy,
  isCtxApiResourcePath: () => isCtxApiResourcePath,
  isCtxLibsRootFromAst: () => isCtxLibsRootFromAst,
  selectCtxApiCapability: () => selectCtxApiCapability,
  trimCtxApiAliasesAfterWrites: () => trimCtxApiAliasesAfterWrites,
  uniqueCtxApiCapabilities: () => uniqueCtxApiCapabilities
});
module.exports = __toCommonJS(ctx_api_exports);
var import_walk = require("../ast/walk");
var import_bindings = require("../ast/bindings");
var import_source = require("../ast/source");
var import_execution = require("../ast/execution");
var import_static_values = require("../ast/static-values");
var import_request_config = require("../ast/request-config");
var import_constants = require("../runtime/constants");
function collectCtxRootAliasesFromAst(ast, source, identifierBindings) {
  return collectCtxRootAliasesFromAstInternal(ast, source, identifierBindings, false);
}
function collectCtxDefiniteRootAliasesFromAst(ast, source, identifierBindings) {
  return collectCtxRootAliasesFromAstInternal(ast, source, identifierBindings, true);
}
function collectCtxRootAliasesFromAstInternal(ast, source, identifierBindings, definiteOnly) {
  const aliases = [];
  const writes = (0, import_execution.collectAstIdentifierWritesFromAst)(ast, source);
  const addAlias = (name, node, ancestors, isVar = false, scopeOverride) => {
    const scope = scopeOverride || (0, import_bindings.getAstBindingScopeRange)(ancestors, source.length, isVar);
    aliases.push({
      capability: "ctx",
      declarationStart: typeof (node == null ? void 0 : node.start) === "number" ? node.start : scope.start,
      executionScope: (0, import_bindings.getAstExecutionScopeRange)(ancestors, source.length),
      name,
      start: typeof (node == null ? void 0 : node.start) === "number" ? node.start : scope.start,
      end: scope.end
    });
  };
  const getActiveAliases = () => (0, import_static_values.trimAstAliasesAfterWrites)(aliases, writes, identifierBindings);
  (0, import_walk.walkAstAncestor)(ast, {
    AssignmentExpression(node, ancestors) {
      var _a;
      const isAliasAssignmentOperator = definiteOnly ? (0, import_static_values.isAstDefiniteAssignmentOperator)(node.operator) : (0, import_static_values.isAstCtxApiAliasAssignmentOperator)(node.operator);
      if (!isAliasAssignmentOperator || ((_a = node.left) == null ? void 0 : _a.type) !== "Identifier") {
        return;
      }
      const isCtxRoot = definiteOnly ? isDefiniteCtxRootFromAst(node.right, getActiveAliases(), identifierBindings) : (0, import_static_values.isCtxRootFromAst)(node.right, getActiveAliases(), identifierBindings);
      if (isCtxRoot) {
        addAlias(
          node.left.name,
          node,
          ancestors,
          false,
          (0, import_static_values.getAstAssignmentTargetScope)(node.left, ancestors, source.length, identifierBindings)
        );
      }
    },
    VariableDeclarator(node, ancestors) {
      var _a;
      const isCtxRoot = definiteOnly ? isDefiniteCtxRootFromAst(node.init, getActiveAliases(), identifierBindings) : (0, import_static_values.isCtxRootFromAst)(node.init, getActiveAliases(), identifierBindings);
      if (((_a = node.id) == null ? void 0 : _a.type) !== "Identifier" || !isCtxRoot) {
        return;
      }
      const declaration = (0, import_bindings.findAstAncestor)(ancestors, "VariableDeclaration");
      addAlias(node.id.name, node, ancestors, (declaration == null ? void 0 : declaration.kind) === "var");
    }
  });
  return (0, import_static_values.trimAstAliasesAfterWrites)(aliases, writes, identifierBindings);
}
function isDefiniteCtxRootFromAst(node, aliases, identifierBindings) {
  const unwrapped = (0, import_bindings.unwrapAstChainExpression)(node);
  if (!unwrapped) {
    return false;
  }
  if (unwrapped.type === "ConditionalExpression") {
    return isDefiniteCtxRootFromAst(unwrapped.consequent, aliases, identifierBindings) && isDefiniteCtxRootFromAst(unwrapped.alternate, aliases, identifierBindings);
  }
  if (unwrapped.type === "SequenceExpression") {
    const expressions = unwrapped.expressions || [];
    return isDefiniteCtxRootFromAst(expressions[expressions.length - 1], aliases, identifierBindings);
  }
  if (unwrapped.type === "AssignmentExpression" && (0, import_static_values.isAstDefiniteAssignmentOperator)(unwrapped.operator)) {
    return isDefiniteCtxRootFromAst(unwrapped.right, aliases, identifierBindings);
  }
  if ((0, import_static_values.isUnshadowedCtxIdentifier)(unwrapped, identifierBindings)) {
    return true;
  }
  if (unwrapped.type !== "Identifier") {
    return false;
  }
  const index = typeof unwrapped.start === "number" ? unwrapped.start : 0;
  return !!(0, import_static_values.resolveAstAliasBinding)(unwrapped.name, index, aliases, identifierBindings);
}
function collectCtxNonFunctionRootAliasesFromAst(ast, source, ctxRootAliases, identifierBindings, modelUse = "") {
  const aliases = [];
  const writes = (0, import_execution.collectAstIdentifierWritesFromAst)(ast, source);
  const addAlias = (name, member, node, ancestors, isVar = false, scopeOverride) => {
    const scope = scopeOverride || (0, import_bindings.getAstBindingScopeRange)(ancestors, source.length, isVar);
    aliases.push({
      capability: `ctx.${member}`,
      declarationStart: typeof (node == null ? void 0 : node.start) === "number" ? node.start : scope.start,
      executionScope: (0, import_bindings.getAstExecutionScopeRange)(ancestors, source.length),
      member,
      name,
      start: typeof (node == null ? void 0 : node.start) === "number" ? node.start : scope.start,
      end: scope.end
    });
  };
  const collectPatternAliases = (pattern, node, ancestors, isVar = false) => {
    (0, import_static_values.collectAstObjectPatternAliases)(pattern, (name, member, aliasNode) => {
      if (isRunJsCtxNonFunctionRoot(member, modelUse)) {
        addAlias(name, member, aliasNode || node, ancestors, isVar);
      }
    });
  };
  (0, import_walk.walkAstAncestor)(ast, {
    AssignmentExpression(node, ancestors) {
      var _a, _b;
      if (!(0, import_static_values.isAstDefiniteAssignmentOperator)(node.operator)) {
        return;
      }
      const member = getCtxNonFunctionRootMemberFromAst(node.right, ctxRootAliases, identifierBindings, modelUse);
      if (((_a = node.left) == null ? void 0 : _a.type) === "Identifier" && member) {
        addAlias(
          node.left.name,
          member,
          node,
          ancestors,
          false,
          (0, import_static_values.getAstAssignmentTargetScope)(node.left, ancestors, source.length, identifierBindings)
        );
        return;
      }
      if (node.operator === "=" && ((_b = node.left) == null ? void 0 : _b.type) === "ObjectPattern") {
        if (isDefiniteCtxRootFromAst(node.right, ctxRootAliases, identifierBindings)) {
          collectPatternAliases(node.left, node, ancestors);
        }
      }
    },
    VariableDeclarator(node, ancestors) {
      var _a, _b;
      const declaration = (0, import_bindings.findAstAncestor)(ancestors, "VariableDeclaration");
      const isVar = (declaration == null ? void 0 : declaration.kind) === "var";
      const member = getCtxNonFunctionRootMemberFromAst(node.init, ctxRootAliases, identifierBindings, modelUse);
      if (((_a = node.id) == null ? void 0 : _a.type) === "Identifier" && member) {
        addAlias(node.id.name, member, node, ancestors, isVar);
        return;
      }
      if (((_b = node.id) == null ? void 0 : _b.type) === "ObjectPattern" && isDefiniteCtxRootFromAst(node.init, ctxRootAliases, identifierBindings)) {
        collectPatternAliases(node.id, node, ancestors, isVar);
      }
    }
  });
  return (0, import_static_values.trimAstAliasesAfterWrites)(aliases, writes, identifierBindings);
}
function collectAstInvalidCtxNonFunctionCall(node, ctxRootAliases, ctxNonFunctionRootAliases, identifierBindings, modelUse = "") {
  const callee = (0, import_bindings.unwrapAstChainExpression)(node == null ? void 0 : node.callee);
  const directMember = getCtxNonFunctionRootMemberFromAst(callee, ctxRootAliases, identifierBindings, modelUse);
  if (directMember) {
    return [
      {
        capability: `ctx.${directMember}`,
        index: typeof (node == null ? void 0 : node.start) === "number" ? node.start : 0,
        member: directMember,
        ruleId: "runjs-ctx-member-not-callable"
      }
    ];
  }
  if ((callee == null ? void 0 : callee.type) !== "Identifier") {
    return [];
  }
  const alias = (0, import_static_values.resolveAstAliasBinding)(
    callee.name,
    typeof callee.start === "number" ? callee.start : typeof (node == null ? void 0 : node.start) === "number" ? node.start : 0,
    ctxNonFunctionRootAliases,
    identifierBindings
  );
  if (!alias) {
    return [];
  }
  return [
    {
      capability: alias.capability,
      index: typeof (node == null ? void 0 : node.start) === "number" ? node.start : alias.start,
      member: alias.member,
      ruleId: "runjs-ctx-member-not-callable"
    }
  ];
}
function getCtxNonFunctionRootMemberFromAst(node, ctxRootAliases, identifierBindings, modelUse) {
  const member = (0, import_bindings.unwrapAstChainExpression)(node);
  if (!member || member.type !== "MemberExpression") {
    return "";
  }
  const propertyName = (0, import_static_values.getAstStaticPropertyName)(member);
  if (!isRunJsCtxNonFunctionRoot(propertyName, modelUse)) {
    return "";
  }
  return isDefiniteCtxRootFromAst(member.object, ctxRootAliases, identifierBindings) ? propertyName : "";
}
function isRunJsCtxNonFunctionRoot(member, modelUse) {
  var _a;
  return import_constants.RUNJS_CTX_NON_FUNCTION_ROOTS.has(member) || Boolean(modelUse && ((_a = import_constants.RUNJS_CTX_NON_FUNCTION_ROOTS_BY_MODEL_USE[modelUse]) == null ? void 0 : _a.has(member)));
}
function collectCtxMethodAliasesFromAst(ast, source, identifierBindings) {
  const aliases = [];
  const addAlias = (name, method, node, ancestors, isVar = false) => {
    const scope = (0, import_bindings.getAstBindingScopeRange)(ancestors, source.length, isVar);
    aliases.push({
      capability: `ctx.${method}`,
      method,
      name,
      start: typeof node.start === "number" ? node.start : scope.start,
      end: scope.end
    });
  };
  (0, import_walk.walkAstAncestor)(ast, {
    AssignmentExpression(node, ancestors) {
      var _a;
      if (node.operator !== "=" || ((_a = node.left) == null ? void 0 : _a.type) !== "Identifier") {
        return;
      }
      const method = (0, import_static_values.getCtxMethodName)(node.right, identifierBindings);
      if (method) {
        addAlias(node.left.name, method, node, ancestors);
      }
    },
    VariableDeclarator(node, ancestors) {
      var _a, _b;
      const method = (0, import_static_values.getCtxMethodName)(node.init, identifierBindings);
      const declaration = (0, import_bindings.findAstAncestor)(ancestors, "VariableDeclaration");
      const isVar = (declaration == null ? void 0 : declaration.kind) === "var";
      if (((_a = node.id) == null ? void 0 : _a.type) === "Identifier" && method) {
        addAlias(node.id.name, method, node, ancestors, isVar);
        return;
      }
      if (((_b = node.id) == null ? void 0 : _b.type) === "ObjectPattern" && (0, import_static_values.isUnshadowedCtxIdentifier)(node.init, identifierBindings)) {
        (0, import_static_values.collectAstObjectPatternAliases)(node.id, (name, member, aliasNode) => {
          if (import_constants.AST_CTX_METHOD_NAMES.has(member)) {
            addAlias(name, member, aliasNode || node, ancestors, isVar);
          }
        });
      }
    }
  });
  return aliases;
}
function collectCtxApiAliasesFromAst(ast, source, identifierBindings) {
  const aliases = [];
  const writes = (0, import_execution.collectAstIdentifierWritesFromAst)(ast, source);
  const addAlias = (name, capability, node, ancestors, isVar = false) => {
    const scope = (0, import_bindings.getAstBindingScopeRange)(ancestors, source.length, isVar);
    aliases.push({
      capability,
      declarationStart: typeof (node == null ? void 0 : node.start) === "number" ? node.start : scope.start,
      executionScope: (0, import_bindings.getAstExecutionScopeRange)(ancestors, source.length),
      name,
      start: typeof (node == null ? void 0 : node.start) === "number" ? node.start : scope.start,
      end: scope.end
    });
  };
  const getActiveAliases = () => trimCtxApiAliasesAfterWrites(aliases, writes, identifierBindings);
  (0, import_walk.walkAstAncestor)(ast, {
    AssignmentExpression(node, ancestors) {
      var _a, _b;
      if (!(0, import_static_values.isAstCtxApiAliasAssignmentOperator)(node.operator)) {
        return;
      }
      const activeAliases = getActiveAliases();
      const capability = getCtxApiCapabilityFromAst(node.right, activeAliases, identifierBindings) || getMaybeCtxApiCapabilityFromAst(node.right, activeAliases, identifierBindings);
      if (((_a = node.left) == null ? void 0 : _a.type) === "Identifier" && capability) {
        addAlias(node.left.name, capability, node, ancestors);
        return;
      }
      if (node.operator === "=" && ((_b = node.left) == null ? void 0 : _b.type) === "ObjectPattern") {
        collectCtxApiObjectPatternAliases(node.left, capability, (name, aliasCapability, aliasNode) => {
          addAlias(name, aliasCapability, aliasNode || node, ancestors);
        });
      }
    },
    VariableDeclarator(node, ancestors) {
      var _a, _b;
      const declaration = (0, import_bindings.findAstAncestor)(ancestors, "VariableDeclaration");
      const isVar = (declaration == null ? void 0 : declaration.kind) === "var";
      const activeAliases = getActiveAliases();
      const capability = getCtxApiCapabilityFromAst(node.init, activeAliases, identifierBindings) || getMaybeCtxApiCapabilityFromAst(node.init, activeAliases, identifierBindings);
      if (((_a = node.id) == null ? void 0 : _a.type) === "Identifier" && capability) {
        addAlias(node.id.name, capability, node, ancestors, isVar);
        return;
      }
      if (((_b = node.id) == null ? void 0 : _b.type) === "ObjectPattern") {
        collectCtxApiObjectPatternAliases(node.id, capability, (name, aliasCapability, aliasNode) => {
          addAlias(name, aliasCapability, aliasNode || node, ancestors, isVar);
        });
      }
    }
  });
  return trimCtxApiAliasesAfterWrites(aliases, writes, identifierBindings);
}
function collectCtxApiObjectPatternAliases(pattern, capability, addAlias) {
  if (capability === "ctx.api") {
    for (const property of (pattern == null ? void 0 : pattern.properties) || []) {
      if (!property || property.type !== "Property") {
        continue;
      }
      const member = (0, import_static_values.getAstStaticPropertyName)(property);
      const alias = (0, import_static_values.getAstBindingIdentifierName)(property.value);
      const aliasNode = (0, import_static_values.getAstBindingIdentifierNode)(property.value);
      if (member && alias && import_constants.RUNJS_CTX_API_ALLOWED_MEMBERS.has(member)) {
        addAlias(alias, `ctx.api.${member}`, aliasNode);
      }
      if (member === "auth") {
        const nestedPattern = (0, import_static_values.getAstObjectPatternFromValue)(property.value);
        if (nestedPattern) {
          collectCtxApiObjectPatternAliases(nestedPattern, "ctx.api.auth", addAlias);
        }
      }
    }
    return;
  }
  if (capability === "ctx.api.auth") {
    (0, import_static_values.collectAstObjectPatternAliases)(pattern, (name, member, aliasNode) => {
      if (import_constants.RUNJS_CTX_API_AUTH_ALLOWED_MEMBERS.has(member)) {
        addAlias(name, `ctx.api.auth.${member}`, aliasNode);
      }
    });
  }
}
function trimCtxApiAliasesAfterWrites(aliases, writes, identifierBindings) {
  return (0, import_static_values.trimAstAliasesAfterWrites)(aliases, writes, identifierBindings);
}
function collectCtxLibsRootAliasesFromAst(ast, source, identifierBindings) {
  const aliases = [];
  const writes = (0, import_execution.collectAstIdentifierWritesFromAst)(ast, source);
  const addAlias = (name, node, ancestors, isVar = false) => {
    const scope = (0, import_bindings.getAstBindingScopeRange)(ancestors, source.length, isVar);
    aliases.push({
      capability: "ctx.libs",
      declarationStart: typeof (node == null ? void 0 : node.start) === "number" ? node.start : scope.start,
      executionScope: (0, import_bindings.getAstExecutionScopeRange)(ancestors, source.length),
      name,
      start: typeof (node == null ? void 0 : node.start) === "number" ? node.start : scope.start,
      end: scope.end
    });
  };
  const getActiveAliases = () => (0, import_static_values.trimAstAliasesAfterWrites)(aliases, writes, identifierBindings);
  (0, import_walk.walkAstAncestor)(ast, {
    AssignmentExpression(node, ancestors) {
      var _a;
      if (!(0, import_static_values.isAstCtxApiAliasAssignmentOperator)(node.operator)) {
        return;
      }
      if (((_a = node.left) == null ? void 0 : _a.type) === "Identifier" && isCtxLibsRootFromAst(node.right, getActiveAliases(), identifierBindings)) {
        addAlias(node.left.name, node, ancestors);
      }
    },
    VariableDeclarator(node, ancestors) {
      var _a;
      if (((_a = node.id) == null ? void 0 : _a.type) !== "Identifier" || !isCtxLibsRootFromAst(node.init, getActiveAliases(), identifierBindings)) {
        return;
      }
      const declaration = (0, import_bindings.findAstAncestor)(ancestors, "VariableDeclaration");
      addAlias(node.id.name, node, ancestors, (declaration == null ? void 0 : declaration.kind) === "var");
    }
  });
  return (0, import_static_values.trimAstAliasesAfterWrites)(aliases, writes, identifierBindings);
}
function collectCtxLibAliasesFromAst(ast, source, rootAliases, identifierBindings) {
  const aliases = [];
  const writes = (0, import_execution.collectAstIdentifierWritesFromAst)(ast, source);
  const addAlias = (name, library, capability, node, ancestors, isVar = false) => {
    const scope = (0, import_bindings.getAstBindingScopeRange)(ancestors, source.length, isVar);
    aliases.push({
      capability,
      declarationStart: typeof (node == null ? void 0 : node.start) === "number" ? node.start : scope.start,
      executionScope: (0, import_bindings.getAstExecutionScopeRange)(ancestors, source.length),
      library,
      name,
      start: typeof (node == null ? void 0 : node.start) === "number" ? node.start : scope.start,
      end: scope.end
    });
  };
  const getActiveAliases = () => (0, import_static_values.trimAstAliasesAfterWrites)(aliases, writes, identifierBindings);
  (0, import_walk.walkAstAncestor)(ast, {
    AssignmentExpression(node, ancestors) {
      var _a, _b;
      if (!(0, import_static_values.isAstCtxApiAliasAssignmentOperator)(node.operator)) {
        return;
      }
      const activeAliases = getActiveAliases();
      const sourcePath = getCtxLibMemberPathFromAst(node.right, activeAliases, rootAliases, identifierBindings, source);
      if (((_a = node.left) == null ? void 0 : _a.type) === "Identifier" && sourcePath && !sourcePath.hasDynamicMember && !sourcePath.members.length) {
        addAlias(node.left.name, sourcePath.library, sourcePath.rootCapability, node, ancestors);
        return;
      }
      if (node.operator === "=" && ((_b = node.left) == null ? void 0 : _b.type) === "ObjectPattern") {
        collectCtxLibObjectPatternAliases(
          node.left,
          node.right,
          rootAliases,
          identifierBindings,
          (name, alias, aliasNode) => {
            addAlias(name, alias.library, alias.capability, aliasNode || node, ancestors);
          }
        );
      }
    },
    VariableDeclarator(node, ancestors) {
      var _a, _b;
      const declaration = (0, import_bindings.findAstAncestor)(ancestors, "VariableDeclaration");
      const isVar = (declaration == null ? void 0 : declaration.kind) === "var";
      const activeAliases = getActiveAliases();
      const sourcePath = getCtxLibMemberPathFromAst(node.init, activeAliases, rootAliases, identifierBindings, source);
      if (((_a = node.id) == null ? void 0 : _a.type) === "Identifier" && sourcePath && !sourcePath.hasDynamicMember && !sourcePath.members.length) {
        addAlias(node.id.name, sourcePath.library, sourcePath.rootCapability, node, ancestors, isVar);
        return;
      }
      if (((_b = node.id) == null ? void 0 : _b.type) === "ObjectPattern") {
        collectCtxLibObjectPatternAliases(
          node.id,
          node.init,
          rootAliases,
          identifierBindings,
          (name, alias, aliasNode) => {
            addAlias(name, alias.library, alias.capability, aliasNode || node, ancestors, isVar);
          }
        );
      }
    }
  });
  return (0, import_static_values.trimAstAliasesAfterWrites)(aliases, writes, identifierBindings);
}
function collectCtxLibObjectPatternAliases(pattern, sourceNode, rootAliases, identifierBindings, addAlias) {
  if (!isCtxLibsRootFromAst(sourceNode, rootAliases, identifierBindings)) {
    return;
  }
  (0, import_static_values.collectAstObjectPatternAliases)(pattern, (name, member, aliasNode) => {
    if (member) {
      addAlias(name, { capability: `ctx.libs.${member}`, library: member }, aliasNode);
    }
  });
}
function collectCtxApiResourceAliasesFromAst(ast, source, ctxApiAliases, stringBindings, staticFilterValueBindings, identifierBindings) {
  const handles = [];
  const methods = [];
  const writes = (0, import_execution.collectAstIdentifierWritesFromAst)(ast, source);
  const addHandleAlias = (name, resourceFactoryCall, node, ancestors, isVar = false) => {
    var _a;
    const scope = (0, import_bindings.getAstBindingScopeRange)(ancestors, source.length, isVar);
    handles.push({
      calleeSource: resourceFactoryCall.calleeSource,
      declarationStart: typeof (node == null ? void 0 : node.start) === "number" ? node.start : scope.start,
      executionScope: (0, import_bindings.getAstExecutionScopeRange)(ancestors, source.length),
      name,
      dataSourceKey: "args" in resourceFactoryCall ? (0, import_request_config.getRunJsApiResourceCallDataSourceKey)(
        resourceFactoryCall.args,
        source,
        stringBindings,
        staticFilterValueBindings,
        identifierBindings
      ) : resourceFactoryCall.dataSourceKey,
      resourceName: "args" in resourceFactoryCall ? (0, import_static_values.resolveRunJsStaticString)((_a = resourceFactoryCall.args) == null ? void 0 : _a[0], source, stringBindings, identifierBindings) : resourceFactoryCall.resourceName,
      start: typeof (node == null ? void 0 : node.start) === "number" ? node.start : scope.start,
      end: scope.end
    });
  };
  const addMethodAlias = (name, method, node, ancestors, isVar = false) => {
    const scope = (0, import_bindings.getAstBindingScopeRange)(ancestors, source.length, isVar);
    methods.push({
      declarationStart: typeof node.start === "number" ? node.start : scope.start,
      executionScope: (0, import_bindings.getAstExecutionScopeRange)(ancestors, source.length),
      method,
      name,
      start: typeof (node == null ? void 0 : node.start) === "number" ? node.start : scope.start,
      end: scope.end
    });
  };
  const getActiveHandles = () => (0, import_static_values.trimAstAliasesAfterWrites)(handles, writes, identifierBindings);
  const getActiveMethods = () => (0, import_static_values.trimAstAliasesAfterWrites)(methods, writes, identifierBindings);
  const collectMethodAliases = (pattern, sourceNode, ancestors, isVar = false) => {
    if (!sourceNode) {
      return;
    }
    (0, import_static_values.collectAstObjectPatternAliases)(pattern, (name, method, aliasNode) => {
      if (import_constants.RUNJS_RESOURCE_METHODS.has(method)) {
        addMethodAlias(name, method, aliasNode || pattern, ancestors, isVar);
      }
    });
  };
  const getDirectResourceHandleSource = (node) => getCtxApiResourceCallFromAst(node, ctxApiAliases, source, identifierBindings) || getCtxApiResourceHandleAliasFromAst(node, getActiveHandles(), identifierBindings);
  const getMaybeResourceHandleSource = (node) => getUniqueCtxApiResourceHandleSource(collectPossibleResourceHandleSources(node));
  const collectPossibleResourceHandleSources = (node) => {
    const directSource = getDirectResourceHandleSource(node);
    if (directSource) {
      return [directSource];
    }
    const unwrapped = (0, import_bindings.unwrapAstChainExpression)(node);
    if (!unwrapped) {
      return [];
    }
    if (unwrapped.type === "ConditionalExpression") {
      return [
        ...collectPossibleResourceHandleSources(unwrapped.consequent),
        ...collectPossibleResourceHandleSources(unwrapped.alternate)
      ];
    }
    if (unwrapped.type === "LogicalExpression") {
      const leftSources = collectPossibleResourceHandleSources(unwrapped.left);
      const rightSources = collectPossibleResourceHandleSources(unwrapped.right);
      return [...leftSources, ...rightSources];
    }
    if (unwrapped.type === "SequenceExpression") {
      const expressions = unwrapped.expressions || [];
      return collectPossibleResourceHandleSources(expressions[expressions.length - 1]);
    }
    if (unwrapped.type === "AssignmentExpression" && (0, import_static_values.isAstCtxApiAliasAssignmentOperator)(unwrapped.operator)) {
      return collectPossibleResourceHandleSources(unwrapped.right);
    }
    return [];
  };
  const getResourceHandleSourceIdentity = (resourceHandleSource) => {
    var _a;
    const dataSourceKey = "args" in resourceHandleSource ? (0, import_request_config.getRunJsApiResourceCallDataSourceKey)(
      resourceHandleSource.args,
      source,
      stringBindings,
      staticFilterValueBindings,
      identifierBindings
    ) : resourceHandleSource.dataSourceKey;
    const resourceName = "args" in resourceHandleSource ? (0, import_static_values.resolveRunJsStaticString)((_a = resourceHandleSource.args) == null ? void 0 : _a[0], source, stringBindings, identifierBindings) : resourceHandleSource.resourceName;
    if (typeof resourceName !== "string" && typeof dataSourceKey !== "string") {
      return void 0;
    }
    return `${dataSourceKey ?? ""}:${resourceName ?? ""}`;
  };
  const getUniqueCtxApiResourceHandleSource = (sources) => {
    if (sources.length <= 1) {
      return sources[0];
    }
    const firstIdentity = getResourceHandleSourceIdentity(sources[0]);
    if (!firstIdentity || sources.some((entry) => getResourceHandleSourceIdentity(entry) !== firstIdentity)) {
      return void 0;
    }
    return sources[0];
  };
  const getDirectResourceMethodSource = (node) => {
    const methodAlias = getCtxApiResourceMethodAliasFromAst(node, getActiveMethods(), identifierBindings);
    if (methodAlias) {
      return { method: methodAlias.method };
    }
    const member = (0, import_bindings.unwrapAstChainExpression)(node);
    if (!member || member.type !== "MemberExpression") {
      return void 0;
    }
    const method = (0, import_static_values.getAstStaticPropertyName)(member);
    if (!import_constants.RUNJS_RESOURCE_METHODS.has(method) || !getMaybeResourceHandleSource(member.object)) {
      return void 0;
    }
    return { method };
  };
  const getMaybeResourceMethodSource = (node) => {
    const sources = collectPossibleResourceMethodSources(node);
    return sources[0];
  };
  const collectPossibleResourceMethodSources = (node) => {
    const directSource = getDirectResourceMethodSource(node);
    if (directSource) {
      return [directSource];
    }
    const unwrapped = (0, import_bindings.unwrapAstChainExpression)(node);
    if (!unwrapped) {
      return [];
    }
    if (unwrapped.type === "ConditionalExpression") {
      return [
        ...collectPossibleResourceMethodSources(unwrapped.consequent),
        ...collectPossibleResourceMethodSources(unwrapped.alternate)
      ];
    }
    if (unwrapped.type === "LogicalExpression") {
      const leftSources = collectPossibleResourceMethodSources(unwrapped.left);
      const rightSources = collectPossibleResourceMethodSources(unwrapped.right);
      return [...leftSources, ...rightSources];
    }
    if (unwrapped.type === "SequenceExpression") {
      const expressions = unwrapped.expressions || [];
      return collectPossibleResourceMethodSources(expressions[expressions.length - 1]);
    }
    if (unwrapped.type === "AssignmentExpression" && (0, import_static_values.isAstCtxApiAliasAssignmentOperator)(unwrapped.operator)) {
      return collectPossibleResourceMethodSources(unwrapped.right);
    }
    return [];
  };
  (0, import_walk.walkAstAncestor)(ast, {
    AssignmentExpression(node, ancestors) {
      var _a, _b;
      if ((0, import_static_values.isAstCtxApiAliasAssignmentOperator)(node.operator) && ((_a = node.left) == null ? void 0 : _a.type) === "Identifier") {
        const resourceMethodSource = getMaybeResourceMethodSource(node.right);
        if (resourceMethodSource) {
          addMethodAlias(node.left.name, resourceMethodSource.method, node, ancestors);
          return;
        }
        const resourceHandleSource = getMaybeResourceHandleSource(node.right);
        if (resourceHandleSource) {
          addHandleAlias(node.left.name, resourceHandleSource, node, ancestors);
          return;
        }
      }
      if (node.operator === "=" && ((_b = node.left) == null ? void 0 : _b.type) === "ObjectPattern") {
        collectMethodAliases(node.left, getMaybeResourceHandleSource(node.right), ancestors);
      }
    },
    VariableDeclarator(node, ancestors) {
      var _a, _b;
      const declaration = (0, import_bindings.findAstAncestor)(ancestors, "VariableDeclaration");
      const isVar = (declaration == null ? void 0 : declaration.kind) === "var";
      if (((_a = node.id) == null ? void 0 : _a.type) === "Identifier") {
        const resourceMethodSource = getMaybeResourceMethodSource(node.init);
        if (resourceMethodSource) {
          addMethodAlias(node.id.name, resourceMethodSource.method, node, ancestors, isVar);
          return;
        }
        const resourceHandleSource2 = getMaybeResourceHandleSource(node.init);
        if (resourceHandleSource2) {
          addHandleAlias(node.id.name, resourceHandleSource2, node, ancestors, isVar);
          return;
        }
      }
      const resourceHandleSource = getMaybeResourceHandleSource(node.init);
      if (((_b = node.id) == null ? void 0 : _b.type) === "ObjectPattern") {
        collectMethodAliases(node.id, resourceHandleSource, ancestors, isVar);
      }
    }
  });
  return {
    handles: (0, import_static_values.trimAstAliasesAfterWrites)(handles, writes, identifierBindings),
    methods: (0, import_static_values.trimAstAliasesAfterWrites)(methods, writes, identifierBindings)
  };
}
function collectAstInvalidApiResourceCall(node, aliases, resourceAliases, source, identifierBindings) {
  var _a, _b, _c;
  const entries = [];
  const callee = (0, import_bindings.unwrapAstChainExpression)(node.callee);
  const chainedResourceMethod = getCtxApiResourceChainedMethodFromAst(
    callee,
    aliases,
    resourceAliases,
    source,
    identifierBindings
  );
  if (chainedResourceMethod) {
    entries.push(chainedResourceMethod);
  }
  const resourceFactoryCall = getCtxApiResourceCallFromAst(node, aliases, source, identifierBindings);
  if (!resourceFactoryCall) {
    return entries;
  }
  const method = (0, import_static_values.resolveAstStaticStringValue)((_a = node.arguments) == null ? void 0 : _a[0], source);
  if (method && import_constants.RUNJS_RESOURCE_METHODS.has(method)) {
    entries.push({
      index: resourceFactoryCall.index,
      match: `${resourceFactoryCall.calleeSource}('${method}')`,
      matchIndex: resourceFactoryCall.index,
      method
    });
  }
  const resourceName = (0, import_static_values.resolveAstStaticStringValue)((_b = node.arguments) == null ? void 0 : _b[0], source);
  const action = (0, import_static_values.resolveAstStaticStringValue)((_c = node.arguments) == null ? void 0 : _c[1], source);
  if (action && import_constants.RUNJS_RESOURCE_METHODS.has(action)) {
    entries.push({
      index: resourceFactoryCall.index,
      match: resourceName ? `${resourceFactoryCall.calleeSource}('${resourceName}', '${action}')` : `${resourceFactoryCall.calleeSource}(..., '${action}')`,
      matchIndex: resourceFactoryCall.index,
      method: action
    });
  }
  return entries;
}
function getCtxApiResourceChainedMethodFromAst(node, aliases, resourceAliases, source, identifierBindings) {
  var _a;
  const callee = (0, import_bindings.unwrapAstChainExpression)(node);
  const wrappedMethod = getWrappedCtxApiResourceChainedMethodFromAst(
    callee,
    aliases,
    resourceAliases,
    source,
    identifierBindings
  );
  if (wrappedMethod) {
    return wrappedMethod;
  }
  const methodAlias = getMaybeCtxApiResourceMethodAliasFromAst(callee, resourceAliases.methods, identifierBindings);
  if (methodAlias) {
    return {
      index: typeof callee.start === "number" ? callee.start : 0,
      match: (0, import_source.getAstSource)(callee, source),
      matchIndex: typeof callee.start === "number" ? callee.start : 0,
      method: methodAlias.method
    };
  }
  if (!callee || callee.type !== "MemberExpression") {
    return void 0;
  }
  const invocationMember = (0, import_static_values.getAstStaticPropertyName)(callee);
  if (invocationMember === "call" || invocationMember === "apply" || invocationMember === "bind") {
    const targetMethod = getCtxApiResourceChainedMethodFromAst(
      callee.object,
      aliases,
      resourceAliases,
      source,
      identifierBindings
    );
    if (targetMethod) {
      return {
        ...targetMethod,
        index: typeof callee.start === "number" ? callee.start : targetMethod.index,
        match: (0, import_source.getAstSource)(callee, source),
        matchIndex: typeof callee.start === "number" ? callee.start : targetMethod.matchIndex
      };
    }
  }
  const method = (0, import_static_values.getAstStaticPropertyName)(callee);
  if (!import_constants.RUNJS_RESOURCE_METHODS.has(method)) {
    return void 0;
  }
  const resourceHandleAlias = getMaybeCtxApiResourceHandleAliasFromAst(
    callee.object,
    resourceAliases.handles,
    identifierBindings
  );
  if (resourceHandleAlias) {
    return {
      index: typeof callee.start === "number" ? callee.start : 0,
      match: (0, import_source.getAstSource)(callee, source),
      matchIndex: typeof callee.start === "number" ? callee.start : 0,
      method
    };
  }
  const objectPath = getCtxApiMemberPathFromAst(callee.object, aliases, identifierBindings);
  if (isCtxApiResourcePath(objectPath)) {
    return {
      index: typeof callee.start === "number" ? callee.start : 0,
      match: (0, import_source.getAstSource)(callee, source),
      matchIndex: typeof callee.start === "number" ? callee.start : 0,
      method
    };
  }
  const resourceFactoryCall = getMaybeCtxApiResourceCallFromAst(callee.object, aliases, source, identifierBindings);
  if (!resourceFactoryCall) {
    return void 0;
  }
  const resourceName = (0, import_static_values.resolveAstStaticStringValue)((_a = resourceFactoryCall.args) == null ? void 0 : _a[0], source);
  return {
    index: resourceFactoryCall.index,
    match: resourceName ? `${resourceFactoryCall.calleeSource}('${resourceName}').${method}` : `${resourceFactoryCall.calleeSource}(...).${method}`,
    matchIndex: resourceFactoryCall.index,
    method
  };
}
function getWrappedCtxApiResourceChainedMethodFromAst(node, aliases, resourceAliases, source, identifierBindings) {
  const unwrapped = (0, import_bindings.unwrapAstChainExpression)(node);
  if (!unwrapped) {
    return void 0;
  }
  const wrapEntry = (entry) => {
    if (!entry) {
      return void 0;
    }
    return {
      ...entry,
      index: typeof unwrapped.start === "number" ? unwrapped.start : entry.index,
      match: (0, import_source.getAstSource)(unwrapped, source),
      matchIndex: typeof unwrapped.start === "number" ? unwrapped.start : entry.matchIndex
    };
  };
  if (unwrapped.type === "ConditionalExpression") {
    return wrapEntry(
      getCtxApiResourceChainedMethodFromAst(
        unwrapped.consequent,
        aliases,
        resourceAliases,
        source,
        identifierBindings
      )
    ) || wrapEntry(
      getCtxApiResourceChainedMethodFromAst(
        unwrapped.alternate,
        aliases,
        resourceAliases,
        source,
        identifierBindings
      )
    );
  }
  if (unwrapped.type === "LogicalExpression") {
    const leftEntry = getCtxApiResourceChainedMethodFromAst(
      unwrapped.left,
      aliases,
      resourceAliases,
      source,
      identifierBindings
    );
    if (unwrapped.operator === "&&") {
      return wrapEntry(
        getCtxApiResourceChainedMethodFromAst(unwrapped.right, aliases, resourceAliases, source, identifierBindings)
      );
    }
    if ((unwrapped.operator === "||" || unwrapped.operator === "??") && leftEntry) {
      return wrapEntry(leftEntry);
    }
    return wrapEntry(leftEntry) || wrapEntry(
      getCtxApiResourceChainedMethodFromAst(unwrapped.right, aliases, resourceAliases, source, identifierBindings)
    );
  }
  if (unwrapped.type === "SequenceExpression") {
    const expressions = unwrapped.expressions || [];
    return wrapEntry(
      getCtxApiResourceChainedMethodFromAst(
        expressions[expressions.length - 1],
        aliases,
        resourceAliases,
        source,
        identifierBindings
      )
    );
  }
  if (unwrapped.type === "AssignmentExpression" && (0, import_static_values.isAstCtxApiAliasAssignmentOperator)(unwrapped.operator)) {
    return wrapEntry(
      getCtxApiResourceChainedMethodFromAst(unwrapped.right, aliases, resourceAliases, source, identifierBindings)
    );
  }
  return void 0;
}
function getCtxApiResourceHandleAliasFromAst(node, aliases, identifierBindings) {
  const unwrapped = (0, import_bindings.unwrapAstChainExpression)(node);
  if ((unwrapped == null ? void 0 : unwrapped.type) !== "Identifier") {
    return void 0;
  }
  return (0, import_static_values.resolveAstAliasBinding)(unwrapped.name, unwrapped.start || 0, aliases, identifierBindings);
}
function getCtxApiResourceMethodAliasFromAst(node, aliases, identifierBindings) {
  const unwrapped = (0, import_bindings.unwrapAstChainExpression)(node);
  if ((unwrapped == null ? void 0 : unwrapped.type) !== "Identifier") {
    return void 0;
  }
  return (0, import_static_values.resolveAstAliasBinding)(unwrapped.name, unwrapped.start || 0, aliases, identifierBindings);
}
function getMaybeCtxApiResourceHandleAliasFromAst(node, aliases, identifierBindings) {
  return getUniqueCtxApiResourceHandleAlias(
    collectMaybeCtxApiResourceHandleAliasesFromAst(node, aliases, identifierBindings)
  );
}
function collectMaybeCtxApiResourceHandleAliasesFromAst(node, aliases, identifierBindings) {
  const directAlias = getCtxApiResourceHandleAliasFromAst(node, aliases, identifierBindings);
  if (directAlias) {
    return [directAlias];
  }
  const unwrapped = (0, import_bindings.unwrapAstChainExpression)(node);
  if (!unwrapped) {
    return [];
  }
  if (unwrapped.type === "ConditionalExpression") {
    return [
      ...collectMaybeCtxApiResourceHandleAliasesFromAst(unwrapped.consequent, aliases, identifierBindings),
      ...collectMaybeCtxApiResourceHandleAliasesFromAst(unwrapped.alternate, aliases, identifierBindings)
    ];
  }
  if (unwrapped.type === "LogicalExpression") {
    const leftAliases = collectMaybeCtxApiResourceHandleAliasesFromAst(unwrapped.left, aliases, identifierBindings);
    return [
      ...leftAliases,
      ...collectMaybeCtxApiResourceHandleAliasesFromAst(unwrapped.right, aliases, identifierBindings)
    ];
  }
  if (unwrapped.type === "SequenceExpression") {
    const expressions = unwrapped.expressions || [];
    return collectMaybeCtxApiResourceHandleAliasesFromAst(
      expressions[expressions.length - 1],
      aliases,
      identifierBindings
    );
  }
  if (unwrapped.type === "AssignmentExpression" && (0, import_static_values.isAstCtxApiAliasAssignmentOperator)(unwrapped.operator)) {
    return collectMaybeCtxApiResourceHandleAliasesFromAst(unwrapped.right, aliases, identifierBindings);
  }
  return [];
}
function getUniqueCtxApiResourceHandleAlias(aliases) {
  if (aliases.length <= 1) {
    return aliases[0];
  }
  const firstIdentity = getCtxApiResourceHandleAliasIdentity(aliases[0]);
  if (!firstIdentity || aliases.some((alias) => getCtxApiResourceHandleAliasIdentity(alias) !== firstIdentity)) {
    return void 0;
  }
  return aliases[0];
}
function getCtxApiResourceHandleAliasIdentity(alias) {
  if (typeof alias.resourceName !== "string" && typeof alias.dataSourceKey !== "string") {
    return "";
  }
  return `${alias.dataSourceKey ?? ""}:${alias.resourceName ?? ""}`;
}
function getMaybeCtxApiResourceMethodAliasFromAst(node, aliases, identifierBindings) {
  const directAlias = getCtxApiResourceMethodAliasFromAst(node, aliases, identifierBindings);
  if (directAlias) {
    return directAlias;
  }
  const unwrapped = (0, import_bindings.unwrapAstChainExpression)(node);
  if (!unwrapped) {
    return void 0;
  }
  if (unwrapped.type === "ConditionalExpression") {
    return getMaybeCtxApiResourceMethodAliasFromAst(unwrapped.consequent, aliases, identifierBindings) || getMaybeCtxApiResourceMethodAliasFromAst(unwrapped.alternate, aliases, identifierBindings);
  }
  if (unwrapped.type === "LogicalExpression") {
    const leftAlias = getMaybeCtxApiResourceMethodAliasFromAst(unwrapped.left, aliases, identifierBindings);
    if (unwrapped.operator === "&&") {
      return getMaybeCtxApiResourceMethodAliasFromAst(unwrapped.right, aliases, identifierBindings);
    }
    if ((unwrapped.operator === "||" || unwrapped.operator === "??") && leftAlias) {
      return leftAlias;
    }
    return leftAlias || getMaybeCtxApiResourceMethodAliasFromAst(unwrapped.right, aliases, identifierBindings);
  }
  if (unwrapped.type === "SequenceExpression") {
    const expressions = unwrapped.expressions || [];
    return getMaybeCtxApiResourceMethodAliasFromAst(expressions[expressions.length - 1], aliases, identifierBindings);
  }
  if (unwrapped.type === "AssignmentExpression" && (0, import_static_values.isAstCtxApiAliasAssignmentOperator)(unwrapped.operator)) {
    return getMaybeCtxApiResourceMethodAliasFromAst(unwrapped.right, aliases, identifierBindings);
  }
  return void 0;
}
function getCtxApiResourceCallFromAst(node, aliases, source, identifierBindings) {
  const call = (0, import_bindings.unwrapAstChainExpression)(node);
  if (!call || call.type !== "CallExpression") {
    return void 0;
  }
  const callee = getCtxApiResourceCalleeFromAst(call.callee, aliases, source, identifierBindings);
  if (!callee) {
    return void 0;
  }
  return {
    args: call.arguments || [],
    calleeSource: callee.source,
    index: typeof call.start === "number" ? call.start : callee.index
  };
}
function getCtxApiResourceCalleeFromAst(node, aliases, source, identifierBindings) {
  const callee = (0, import_bindings.unwrapAstChainExpression)(node);
  if (!callee) {
    return void 0;
  }
  const path = getCtxApiMemberPathFromAst(callee, aliases, identifierBindings);
  if (isCtxApiResourcePath(path)) {
    return {
      index: typeof callee.start === "number" ? callee.start : 0,
      source: (0, import_source.getAstSource)(callee, source)
    };
  }
  const wrapEntry = (entry) => {
    if (!entry) {
      return void 0;
    }
    return {
      index: typeof callee.start === "number" ? callee.start : entry.index,
      source: (0, import_source.getAstSource)(callee, source)
    };
  };
  if (callee.type === "ConditionalExpression") {
    return wrapEntry(getCtxApiResourceCalleeFromAst(callee.consequent, aliases, source, identifierBindings)) || wrapEntry(getCtxApiResourceCalleeFromAst(callee.alternate, aliases, source, identifierBindings));
  }
  if (callee.type === "LogicalExpression") {
    const leftEntry = getCtxApiResourceCalleeFromAst(callee.left, aliases, source, identifierBindings);
    if (callee.operator === "&&") {
      return wrapEntry(getCtxApiResourceCalleeFromAst(callee.right, aliases, source, identifierBindings));
    }
    if ((callee.operator === "||" || callee.operator === "??") && leftEntry) {
      return wrapEntry(leftEntry);
    }
    return wrapEntry(leftEntry) || wrapEntry(getCtxApiResourceCalleeFromAst(callee.right, aliases, source, identifierBindings));
  }
  if (callee.type === "SequenceExpression") {
    const expressions = callee.expressions || [];
    return wrapEntry(
      getCtxApiResourceCalleeFromAst(expressions[expressions.length - 1], aliases, source, identifierBindings)
    );
  }
  if (callee.type === "AssignmentExpression" && (0, import_static_values.isAstCtxApiAliasAssignmentOperator)(callee.operator)) {
    return wrapEntry(getCtxApiResourceCalleeFromAst(callee.right, aliases, source, identifierBindings));
  }
  return void 0;
}
function getMaybeCtxApiResourceCallFromAst(node, aliases, source, identifierBindings) {
  return getUniqueCtxApiResourceCall(
    collectMaybeCtxApiResourceCallsFromAst(node, aliases, source, identifierBindings),
    source
  );
}
function collectMaybeCtxApiResourceCallsFromAst(node, aliases, source, identifierBindings) {
  const directCall = getCtxApiResourceCallFromAst(node, aliases, source, identifierBindings);
  if (directCall) {
    return [directCall];
  }
  const unwrapped = (0, import_bindings.unwrapAstChainExpression)(node);
  if (!unwrapped) {
    return [];
  }
  if (unwrapped.type === "ConditionalExpression") {
    return [
      ...collectMaybeCtxApiResourceCallsFromAst(unwrapped.consequent, aliases, source, identifierBindings),
      ...collectMaybeCtxApiResourceCallsFromAst(unwrapped.alternate, aliases, source, identifierBindings)
    ];
  }
  if (unwrapped.type === "LogicalExpression") {
    const leftCalls = collectMaybeCtxApiResourceCallsFromAst(unwrapped.left, aliases, source, identifierBindings);
    return [
      ...leftCalls,
      ...collectMaybeCtxApiResourceCallsFromAst(unwrapped.right, aliases, source, identifierBindings)
    ];
  }
  if (unwrapped.type === "SequenceExpression") {
    const expressions = unwrapped.expressions || [];
    return collectMaybeCtxApiResourceCallsFromAst(
      expressions[expressions.length - 1],
      aliases,
      source,
      identifierBindings
    );
  }
  if (unwrapped.type === "AssignmentExpression" && (0, import_static_values.isAstCtxApiAliasAssignmentOperator)(unwrapped.operator)) {
    return collectMaybeCtxApiResourceCallsFromAst(unwrapped.right, aliases, source, identifierBindings);
  }
  return [];
}
function getUniqueCtxApiResourceCall(calls, source) {
  if (calls.length <= 1) {
    return calls[0];
  }
  const firstIdentity = getCtxApiResourceCallIdentity(calls[0], source);
  if (!firstIdentity || calls.some((call) => getCtxApiResourceCallIdentity(call, source) !== firstIdentity)) {
    return void 0;
  }
  return calls[0];
}
function getCtxApiResourceCallIdentity(call, source) {
  var _a, _b, _c;
  const resourceSource = (0, import_source.getAstSource)((_a = call.args) == null ? void 0 : _a[0], source);
  if (!resourceSource) {
    return "";
  }
  return [resourceSource, (0, import_source.getAstSource)((_b = call.args) == null ? void 0 : _b[1], source), (0, import_source.getAstSource)((_c = call.args) == null ? void 0 : _c[2], source)].join(":");
}
function filterInvalidCtxApiMemberAccessesForResourceCalls(memberAccesses, resourceCalls) {
  const resourceCallMatches = new Set(resourceCalls.map((entry) => entry.match));
  const resourceCallMatchRanges = new Set(
    resourceCalls.filter((entry) => typeof entry.matchIndex === "number").map((entry) => `${entry.matchIndex}:${entry.match}`)
  );
  return memberAccesses.filter((entry) => {
    if (entry.ruleId !== "runjs-ctx-api-member-unknown") {
      return true;
    }
    if (!entry.match || !entry.capability.startsWith("ctx.api.resource.")) {
      return true;
    }
    if (typeof entry.matchIndex === "number") {
      return !resourceCallMatchRanges.has(`${entry.matchIndex}:${entry.match}`);
    }
    return !resourceCallMatches.has(entry.match);
  });
}
function isCtxApiResourcePath(path) {
  return !!path && !path.hasDynamicMember && path.members.length === 1 && path.members[0].name === "resource";
}
function collectAstInvalidCtxLibPatternAccesses(ast, aliases, rootAliases, identifierBindings, source) {
  const entries = [];
  const collectPattern = (pattern, sourceNode) => {
    const sourcePath = getCtxLibMemberPathFromAst(sourceNode, aliases, rootAliases, identifierBindings, source);
    if (!sourcePath || sourcePath.hasDynamicMember || sourcePath.members.length) {
      return;
    }
    collectInvalidCtxLibObjectPatternAccesses(pattern, sourcePath).forEach((entry) => entries.push(entry));
  };
  (0, import_walk.walkAstAncestor)(ast, {
    AssignmentExpression(node) {
      var _a;
      if (node.operator !== "=" || ((_a = node.left) == null ? void 0 : _a.type) !== "ObjectPattern") {
        return;
      }
      collectPattern(node.left, node.right);
    },
    VariableDeclarator(node) {
      var _a;
      if (((_a = node.id) == null ? void 0 : _a.type) !== "ObjectPattern") {
        return;
      }
      collectPattern(node.id, node.init);
    }
  });
  return (0, import_bindings.dedupeIndexedEntries)(entries);
}
function collectInvalidCtxLibObjectPatternAccesses(pattern, sourcePath) {
  var _a;
  const entries = [];
  for (const property of (pattern == null ? void 0 : pattern.properties) || []) {
    if (!property || property.type !== "Property") {
      continue;
    }
    const member = (0, import_static_values.getAstStaticPropertyName)(property);
    if (!member) {
      continue;
    }
    const invalidAccess = buildInvalidCtxLibMemberAccess({
      ...sourcePath,
      members: [
        {
          accessKind: "destructure",
          index: typeof ((_a = property.key) == null ? void 0 : _a.start) === "number" ? property.key.start : property.start || 0,
          name: member
        }
      ]
    });
    if (invalidAccess) {
      entries.push(invalidAccess);
    }
  }
  return entries;
}
function collectAstInvalidCtxLibMemberAccess(node, aliases, rootAliases, identifierBindings, source) {
  const path = getCtxLibMemberPathFromAst(node, aliases, rootAliases, identifierBindings, source);
  if (!path || path.hasDynamicMember || !path.members.length) {
    return void 0;
  }
  return buildInvalidCtxLibMemberAccess(path);
}
function buildInvalidCtxLibMemberAccess(path) {
  const allowedMembers = import_constants.RUNJS_CTX_LIB_ALLOWED_MEMBERS_BY_LIBRARY.get(path.library);
  const member = path.members[0];
  if (!allowedMembers || !member || allowedMembers.has(member.name)) {
    return void 0;
  }
  return {
    accessKind: member.accessKind,
    capability: getCtxLibMemberCapability(path.rootCapability, member),
    index: member.index,
    library: path.library,
    member: member.name,
    ruleId: "runjs-ctx-libs-member-unknown",
    suggestedImport: getSuggestedCtxLibMemberImport(path.library, member.name)
  };
}
function getCtxLibMemberCapability(rootCapability, member) {
  return member.accessKind === "bracket" ? `${rootCapability}[${JSON.stringify(member.name)}]` : `${rootCapability}.${member.name}`;
}
function getSuggestedCtxLibMemberImport(library, member) {
  if (library === "antd" && member === "colors") {
    return "@ant-design/colors";
  }
  return void 0;
}
function getCtxLibMemberPathFromAst(node, aliases, rootAliases, identifierBindings, source) {
  var _a;
  const unwrapped = (0, import_bindings.unwrapAstChainExpression)(node);
  if (!unwrapped) {
    return void 0;
  }
  if (unwrapped.type === "Identifier") {
    const alias = (0, import_static_values.resolveAstAliasBinding)(unwrapped.name, unwrapped.start || 0, aliases, identifierBindings);
    if (!alias) {
      return void 0;
    }
    const index = typeof unwrapped.start === "number" ? unwrapped.start : alias.start;
    return {
      dynamicIndex: index,
      hasDynamicMember: false,
      library: alias.library,
      libraryIndex: index,
      memberIndex: index,
      members: [],
      rootCapability: alias.capability
    };
  }
  if (unwrapped.type !== "MemberExpression") {
    return void 0;
  }
  const objectPath = getCtxLibMemberPathFromAst(unwrapped.object, aliases, rootAliases, identifierBindings, source);
  if (objectPath) {
    const propertyName = (0, import_static_values.getAstStaticPropertyName)(unwrapped);
    const propertyIndex = typeof ((_a = unwrapped.property) == null ? void 0 : _a.start) === "number" ? unwrapped.property.start : unwrapped.start || 0;
    return {
      ...objectPath,
      dynamicIndex: propertyName ? objectPath.dynamicIndex : propertyIndex,
      hasDynamicMember: objectPath.hasDynamicMember || !propertyName,
      memberIndex: objectPath.members.length ? objectPath.memberIndex : propertyIndex,
      members: propertyName ? [
        ...objectPath.members,
        {
          accessKind: unwrapped.computed ? "bracket" : "member",
          index: propertyIndex,
          name: propertyName
        }
      ] : objectPath.members
    };
  }
  return getDirectCtxLibPathFromAst(unwrapped, rootAliases, identifierBindings, source);
}
function getDirectCtxLibPathFromAst(node, rootAliases, identifierBindings, source) {
  var _a;
  const member = (0, import_bindings.unwrapAstChainExpression)(node);
  if (!member || member.type !== "MemberExpression") {
    return void 0;
  }
  const propertyName = (0, import_static_values.getAstStaticPropertyName)(member);
  if (!propertyName) {
    return void 0;
  }
  const propertyIndex = typeof ((_a = member.property) == null ? void 0 : _a.start) === "number" ? member.property.start : member.start || 0;
  if (isCtxLibsRootFromAst(member.object, rootAliases, identifierBindings)) {
    return {
      dynamicIndex: propertyIndex,
      hasDynamicMember: false,
      library: propertyName,
      libraryIndex: propertyIndex,
      memberIndex: propertyIndex,
      members: [],
      rootCapability: (0, import_source.getAstSource)(member, source) || `ctx.libs.${propertyName}`
    };
  }
  if (import_constants.CANONICAL_CTX_LIB_MEMBERS.includes(propertyName) && (0, import_static_values.isUnshadowedCtxIdentifier)(member.object, identifierBindings)) {
    return {
      dynamicIndex: propertyIndex,
      hasDynamicMember: false,
      library: propertyName,
      libraryIndex: propertyIndex,
      memberIndex: propertyIndex,
      members: [],
      rootCapability: (0, import_source.getAstSource)(member, source) || `ctx.${propertyName}`
    };
  }
  return void 0;
}
function isCtxLibsRootFromAst(node, rootAliases, identifierBindings) {
  const unwrapped = (0, import_bindings.unwrapAstChainExpression)(node);
  if (!unwrapped) {
    return false;
  }
  if (unwrapped.type === "Identifier") {
    return !!(0, import_static_values.resolveAstAliasBinding)(unwrapped.name, unwrapped.start || 0, rootAliases, identifierBindings);
  }
  return unwrapped.type === "MemberExpression" && (0, import_static_values.getAstStaticPropertyName)(unwrapped) === "libs" && (0, import_static_values.isUnshadowedCtxIdentifier)(unwrapped.object, identifierBindings);
}
function collectAstInvalidCtxApiPatternAccesses(ast, aliases, identifierBindings) {
  const entries = [];
  const collectPattern = (pattern, capability) => {
    collectInvalidCtxApiObjectPatternAccesses(pattern, getCtxApiCapabilityMemberPrefix(capability)).forEach(
      (entry) => entries.push(entry)
    );
  };
  (0, import_walk.walkAstAncestor)(ast, {
    AssignmentExpression(node) {
      var _a;
      if (node.operator !== "=" || ((_a = node.left) == null ? void 0 : _a.type) !== "ObjectPattern") {
        return;
      }
      const capability = getCtxApiCapabilityFromAst(node.right, aliases, identifierBindings) || getMaybeCtxApiCapabilityFromAst(node.right, aliases, identifierBindings);
      if (capability) {
        collectPattern(node.left, capability);
      }
    },
    VariableDeclarator(node) {
      var _a;
      if (((_a = node.id) == null ? void 0 : _a.type) !== "ObjectPattern") {
        return;
      }
      const capability = getCtxApiCapabilityFromAst(node.init, aliases, identifierBindings) || getMaybeCtxApiCapabilityFromAst(node.init, aliases, identifierBindings);
      if (capability) {
        collectPattern(node.id, capability);
      }
    }
  });
  return (0, import_bindings.dedupeIndexedEntries)(entries);
}
function getCtxApiCapabilityMemberPrefix(capability) {
  if (capability === "ctx.api.auth") {
    return ["auth"];
  }
  if (capability.startsWith("ctx.api.auth.")) {
    return ["auth", capability.slice("ctx.api.auth.".length)];
  }
  if (capability === "ctx.api.request") {
    return ["request"];
  }
  if (capability === "ctx.api.resource") {
    return ["resource"];
  }
  return [];
}
function collectInvalidCtxApiObjectPatternAccesses(pattern, prefix) {
  var _a;
  const entries = [];
  for (const property of (pattern == null ? void 0 : pattern.properties) || []) {
    if (!property) {
      continue;
    }
    if (property.type === "RestElement") {
      const dynamicAccess = buildInvalidCtxApiMemberAccess([...prefix, "[...]"], property.start || 0, true);
      if (dynamicAccess) {
        entries.push(dynamicAccess);
      }
      continue;
    }
    if (property.type !== "Property") {
      continue;
    }
    const member = (0, import_static_values.getAstStaticPropertyName)(property);
    if (!member) {
      const dynamicAccess = buildInvalidCtxApiMemberAccess([...prefix, "[...]"], property.start || 0, true);
      if (dynamicAccess) {
        entries.push(dynamicAccess);
      }
      continue;
    }
    const memberPath = [...prefix, member];
    const invalidAccess = buildInvalidCtxApiMemberAccess(
      memberPath,
      typeof ((_a = property.key) == null ? void 0 : _a.start) === "number" ? property.key.start : property.start || 0
    );
    if (invalidAccess) {
      entries.push(invalidAccess);
      continue;
    }
    const nestedPattern = (0, import_static_values.getAstObjectPatternFromValue)(property.value);
    if (nestedPattern) {
      collectInvalidCtxApiObjectPatternAccesses(nestedPattern, memberPath).forEach((entry) => entries.push(entry));
    }
  }
  return entries;
}
function collectAstInvalidCtxApiMemberAccess(node, aliases, identifierBindings, source) {
  const access = getCtxApiMemberAccessFromAst(node, aliases, identifierBindings);
  if (!access || !access.memberPath.length) {
    return void 0;
  }
  const invalidAccess = buildInvalidCtxApiMemberAccess(
    access.memberPath,
    access.hasDynamicMember ? access.dynamicIndex : access.memberIndex,
    access.hasDynamicMember
  );
  return invalidAccess ? { ...invalidAccess, match: (0, import_source.getAstSource)(node, source), matchIndex: node.start || 0 } : void 0;
}
function buildInvalidCtxApiMemberAccess(memberPath, index, hasDynamicMember = false) {
  const capability = `ctx.api.${memberPath.join(".")}`;
  const topLevelMember = memberPath[0];
  if (hasDynamicMember) {
    return {
      capability,
      index,
      ruleId: "runjs-ctx-api-member-dynamic-unresolved"
    };
  }
  if (!import_constants.RUNJS_CTX_API_ALLOWED_MEMBERS.has(topLevelMember)) {
    return {
      capability,
      index,
      member: topLevelMember,
      ruleId: "runjs-ctx-api-member-unknown"
    };
  }
  if (topLevelMember === "request" && memberPath.length > 1) {
    return {
      capability,
      index,
      member: memberPath[1],
      ruleId: "runjs-ctx-api-member-unknown"
    };
  }
  if (topLevelMember === "resource" && memberPath.length > 1) {
    return {
      capability,
      index,
      member: memberPath[1],
      ruleId: "runjs-ctx-api-member-unknown"
    };
  }
  if (topLevelMember === "auth" && memberPath.length > 1) {
    const authMember = memberPath[1];
    if (!import_constants.RUNJS_CTX_API_AUTH_ALLOWED_MEMBERS.has(authMember)) {
      return {
        capability,
        index,
        member: authMember,
        ruleId: "runjs-ctx-api-auth-member-unsupported"
      };
    }
  }
  return void 0;
}
function collectAstInvalidCtxApiReadonlyWrites(node, aliases, identifierBindings) {
  const entries = [];
  collectAstWriteTargetNodes(node, (target) => {
    const path = getCtxApiMemberPathFromAst(target, aliases, identifierBindings);
    if (!(path == null ? void 0 : path.isCtxApi) || path.hasDynamicMember) {
      return;
    }
    const memberPath = path.members.map((member) => member.name);
    if (memberPath[0] !== "auth") {
      return;
    }
    if (memberPath.length === 1 || import_constants.RUNJS_CTX_API_AUTH_ALLOWED_MEMBERS.has(memberPath[1])) {
      entries.push({
        capability: `ctx.api.${memberPath.join(".")}`,
        index: path.memberIndex,
        member: memberPath[1] || "auth",
        ruleId: "runjs-ctx-api-auth-member-readonly"
      });
    }
  });
  return entries;
}
function collectAstWriteTargetNodes(node, visit) {
  const unwrapped = (0, import_bindings.unwrapAstChainExpression)(node);
  if (!unwrapped) {
    return;
  }
  if (unwrapped.type === "MemberExpression") {
    visit(unwrapped);
    return;
  }
  if (unwrapped.type === "AssignmentPattern") {
    collectAstWriteTargetNodes(unwrapped.left, visit);
    return;
  }
  if (unwrapped.type === "RestElement") {
    collectAstWriteTargetNodes(unwrapped.argument, visit);
    return;
  }
  if (unwrapped.type === "ArrayPattern") {
    for (const element of unwrapped.elements || []) {
      collectAstWriteTargetNodes(element, visit);
    }
    return;
  }
  if (unwrapped.type === "ObjectPattern") {
    for (const property of unwrapped.properties || []) {
      if (!property) {
        continue;
      }
      if (property.type === "RestElement") {
        collectAstWriteTargetNodes(property.argument, visit);
        continue;
      }
      if (property.type === "Property") {
        collectAstWriteTargetNodes(property.value, visit);
      }
    }
  }
}
function getCtxApiMemberAccessFromAst(node, aliases, identifierBindings) {
  const path = getCtxApiMemberPathFromAst(node, aliases, identifierBindings);
  if (!(path == null ? void 0 : path.isCtxApi)) {
    return void 0;
  }
  const memberPath = path.members.map((member) => member.name);
  if (path.hasDynamicMember) {
    memberPath.push("[...]");
  }
  if (!memberPath.length) {
    return void 0;
  }
  return {
    dynamicIndex: path.dynamicIndex,
    hasDynamicMember: path.hasDynamicMember,
    memberIndex: path.memberIndex,
    memberPath
  };
}
function getCtxApiMemberPathFromAst(node, aliases, identifierBindings) {
  var _a, _b, _c, _d;
  const unwrapped = (0, import_bindings.unwrapAstChainExpression)(node);
  if (!unwrapped) {
    return void 0;
  }
  if (unwrapped.type === "Identifier") {
    const alias = (0, import_static_values.resolveAstAliasBinding)(unwrapped.name, unwrapped.start || 0, aliases, identifierBindings);
    if (!alias) {
      return void 0;
    }
    return {
      dynamicIndex: unwrapped.start || 0,
      hasDynamicMember: false,
      isCtxApi: true,
      memberIndex: unwrapped.start || 0,
      members: getCtxApiAliasMemberPath(alias, unwrapped.start || 0)
    };
  }
  if (unwrapped.type !== "MemberExpression") {
    return void 0;
  }
  const objectPath = getCtxApiMemberPathFromAst(unwrapped.object, aliases, identifierBindings);
  if (objectPath == null ? void 0 : objectPath.isCtxApi) {
    const propertyName2 = (0, import_static_values.getAstStaticPropertyName)(unwrapped);
    const propertyIndex2 = typeof ((_a = unwrapped.property) == null ? void 0 : _a.start) === "number" ? unwrapped.property.start : unwrapped.start || 0;
    return {
      ...objectPath,
      dynamicIndex: propertyName2 ? objectPath.dynamicIndex : propertyIndex2,
      hasDynamicMember: objectPath.hasDynamicMember || !propertyName2,
      memberIndex: objectPath.members.length ? objectPath.memberIndex : propertyIndex2,
      members: propertyName2 ? [...objectPath.members, { index: propertyIndex2, name: propertyName2 }] : objectPath.members
    };
  }
  const objectCapability = getMaybeCtxApiCapabilityFromAst(unwrapped.object, aliases, identifierBindings);
  if (objectCapability) {
    const propertyName2 = (0, import_static_values.getAstStaticPropertyName)(unwrapped);
    const propertyIndex2 = typeof ((_b = unwrapped.property) == null ? void 0 : _b.start) === "number" ? unwrapped.property.start : unwrapped.start || 0;
    const members = getCtxApiCapabilityMemberPath(objectCapability, ((_c = unwrapped.object) == null ? void 0 : _c.start) || propertyIndex2);
    return {
      dynamicIndex: propertyName2 ? propertyIndex2 : propertyIndex2,
      hasDynamicMember: !propertyName2,
      isCtxApi: true,
      memberIndex: members.length ? members[0].index : propertyIndex2,
      members: propertyName2 ? [...members, { index: propertyIndex2, name: propertyName2 }] : members
    };
  }
  if (!(0, import_static_values.isUnshadowedCtxIdentifier)(unwrapped.object, identifierBindings)) {
    return void 0;
  }
  const propertyName = (0, import_static_values.getAstStaticPropertyName)(unwrapped);
  if (propertyName !== "api") {
    return void 0;
  }
  const propertyIndex = typeof ((_d = unwrapped.property) == null ? void 0 : _d.start) === "number" ? unwrapped.property.start : unwrapped.start || 0;
  return {
    dynamicIndex: propertyIndex,
    hasDynamicMember: false,
    isCtxApi: true,
    memberIndex: propertyIndex,
    members: []
  };
}
function getCtxApiAliasMemberPath(alias, index) {
  return getCtxApiCapabilityMemberPath(alias.capability, index);
}
function getCtxApiCapabilityMemberPath(capability, index) {
  if (capability === "ctx.api.auth") {
    return [{ index, name: "auth" }];
  }
  if (capability.startsWith("ctx.api.auth.")) {
    return [
      { index, name: "auth" },
      { index, name: capability.slice("ctx.api.auth.".length) }
    ];
  }
  if (capability === "ctx.api.request") {
    return [{ index, name: "request" }];
  }
  if (capability === "ctx.api.resource") {
    return [{ index, name: "resource" }];
  }
  return [];
}
function getCtxApiCapabilityFromAst(node, aliases, identifierBindings) {
  const path = getCtxApiMemberPathFromAst(node, aliases, identifierBindings);
  if (!(path == null ? void 0 : path.isCtxApi) || path.hasDynamicMember) {
    return "";
  }
  if (!path.members.length) {
    return "ctx.api";
  }
  if (path.members.length === 1 && import_constants.RUNJS_CTX_API_ALLOWED_MEMBERS.has(path.members[0].name)) {
    return `ctx.api.${path.members[0].name}`;
  }
  if (path.members.length === 2 && path.members[0].name === "auth" && import_constants.RUNJS_CTX_API_AUTH_ALLOWED_MEMBERS.has(path.members[1].name)) {
    return `ctx.api.auth.${path.members[1].name}`;
  }
  return "";
}
function getMaybeCtxApiCapabilityFromAst(node, aliases, identifierBindings) {
  return selectCtxApiCapability(collectPossibleCtxApiCapabilitiesFromAst(node, aliases, identifierBindings));
}
function collectPossibleCtxApiCapabilitiesFromAst(node, aliases, identifierBindings) {
  const unwrapped = (0, import_bindings.unwrapAstChainExpression)(node);
  if (!unwrapped) {
    return [];
  }
  const directCapability = getCtxApiCapabilityFromAst(unwrapped, aliases, identifierBindings);
  if (directCapability) {
    return [directCapability];
  }
  if (unwrapped.type === "ConditionalExpression") {
    return uniqueCtxApiCapabilities([
      ...collectPossibleCtxApiCapabilitiesFromAst(unwrapped.consequent, aliases, identifierBindings),
      ...collectPossibleCtxApiCapabilitiesFromAst(unwrapped.alternate, aliases, identifierBindings)
    ]);
  }
  if (unwrapped.type === "LogicalExpression") {
    const leftCapabilities = collectPossibleCtxApiCapabilitiesFromAst(unwrapped.left, aliases, identifierBindings);
    const rightCapabilities = collectPossibleCtxApiCapabilitiesFromAst(unwrapped.right, aliases, identifierBindings);
    if (unwrapped.operator === "&&" && leftCapabilities.length) {
      return leftCapabilities.every(isCtxApiCapabilityDefinitelyTruthy) ? uniqueCtxApiCapabilities(rightCapabilities) : uniqueCtxApiCapabilities([...leftCapabilities, ...rightCapabilities]);
    }
    if ((unwrapped.operator === "||" || unwrapped.operator === "??") && leftCapabilities.length) {
      return leftCapabilities.every(isCtxApiCapabilityDefinitelyTruthy) ? uniqueCtxApiCapabilities(leftCapabilities) : uniqueCtxApiCapabilities([...leftCapabilities, ...rightCapabilities]);
    }
    return uniqueCtxApiCapabilities([...leftCapabilities, ...rightCapabilities]);
  }
  if (unwrapped.type === "SequenceExpression") {
    const expressions = unwrapped.expressions || [];
    return collectPossibleCtxApiCapabilitiesFromAst(expressions[expressions.length - 1], aliases, identifierBindings);
  }
  if (unwrapped.type === "AssignmentExpression" && (0, import_static_values.isAstCtxApiAliasAssignmentOperator)(unwrapped.operator)) {
    return collectPossibleCtxApiCapabilitiesFromAst(unwrapped.right, aliases, identifierBindings);
  }
  return [];
}
function selectCtxApiCapability(capabilities) {
  const uniqueCapabilities = uniqueCtxApiCapabilities(capabilities);
  if (!uniqueCapabilities.length) {
    return "";
  }
  if (uniqueCapabilities.length === 1) {
    return uniqueCapabilities[0];
  }
  if (uniqueCapabilities.some((capability) => capability === "ctx.api")) {
    return "ctx.api";
  }
  const topLevelMembers = new Set(uniqueCapabilities.map((capability) => capability.split(".")[2]));
  if (topLevelMembers.size > 1) {
    return "ctx.api";
  }
  const topLevelMember = [...topLevelMembers][0];
  if (topLevelMember === "auth") {
    return "ctx.api.auth";
  }
  if (topLevelMember === "request" || topLevelMember === "resource") {
    return `ctx.api.${topLevelMember}`;
  }
  return "ctx.api";
}
function uniqueCtxApiCapabilities(capabilities) {
  return [...new Set(capabilities.filter(Boolean))];
}
function isCtxApiCapabilityDefinitelyTruthy(capability) {
  return capability === "ctx.api" || capability === "ctx.api.auth" || capability === "ctx.api.request" || capability === "ctx.api.resource" || capability === "ctx.api.auth.authenticator";
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  buildInvalidCtxApiMemberAccess,
  buildInvalidCtxLibMemberAccess,
  collectAstInvalidApiResourceCall,
  collectAstInvalidCtxApiMemberAccess,
  collectAstInvalidCtxApiPatternAccesses,
  collectAstInvalidCtxApiReadonlyWrites,
  collectAstInvalidCtxLibMemberAccess,
  collectAstInvalidCtxLibPatternAccesses,
  collectAstInvalidCtxNonFunctionCall,
  collectAstWriteTargetNodes,
  collectCtxApiAliasesFromAst,
  collectCtxApiObjectPatternAliases,
  collectCtxApiResourceAliasesFromAst,
  collectCtxDefiniteRootAliasesFromAst,
  collectCtxLibAliasesFromAst,
  collectCtxLibObjectPatternAliases,
  collectCtxLibsRootAliasesFromAst,
  collectCtxMethodAliasesFromAst,
  collectCtxNonFunctionRootAliasesFromAst,
  collectCtxRootAliasesFromAst,
  collectInvalidCtxApiObjectPatternAccesses,
  collectInvalidCtxLibObjectPatternAccesses,
  collectMaybeCtxApiResourceCallsFromAst,
  collectMaybeCtxApiResourceHandleAliasesFromAst,
  collectPossibleCtxApiCapabilitiesFromAst,
  filterInvalidCtxApiMemberAccessesForResourceCalls,
  getCtxApiAliasMemberPath,
  getCtxApiCapabilityFromAst,
  getCtxApiCapabilityMemberPath,
  getCtxApiCapabilityMemberPrefix,
  getCtxApiMemberAccessFromAst,
  getCtxApiMemberPathFromAst,
  getCtxApiResourceCallFromAst,
  getCtxApiResourceCallIdentity,
  getCtxApiResourceCalleeFromAst,
  getCtxApiResourceChainedMethodFromAst,
  getCtxApiResourceHandleAliasFromAst,
  getCtxApiResourceHandleAliasIdentity,
  getCtxApiResourceMethodAliasFromAst,
  getCtxLibMemberCapability,
  getCtxLibMemberPathFromAst,
  getDirectCtxLibPathFromAst,
  getMaybeCtxApiCapabilityFromAst,
  getMaybeCtxApiResourceCallFromAst,
  getMaybeCtxApiResourceHandleAliasFromAst,
  getMaybeCtxApiResourceMethodAliasFromAst,
  getSuggestedCtxLibMemberImport,
  getUniqueCtxApiResourceCall,
  getUniqueCtxApiResourceHandleAlias,
  getWrappedCtxApiResourceChainedMethodFromAst,
  isCtxApiCapabilityDefinitelyTruthy,
  isCtxApiResourcePath,
  isCtxLibsRootFromAst,
  selectCtxApiCapability,
  trimCtxApiAliasesAfterWrites,
  uniqueCtxApiCapabilities
});
