/**
 * 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 scan_exports = {};
__export(scan_exports, {
  scanJavaScriptSource: () => scanJavaScriptSource
});
module.exports = __toCommonJS(scan_exports);
var import_source = require("../ast/source");
var import_walk = require("../ast/walk");
var import_bindings = require("../ast/bindings");
var import_source_patterns = require("./source-patterns");
var import_static_bindings = require("../ast/static-bindings");
var import_static_values = require("../ast/static-values");
var import_react = require("./react");
var import_react_render = require("./react-render");
var import_ctx_api = require("./ctx-api");
var import_resource = require("./resource");
var import_filter = require("./filter");
var import_constants = require("../runtime/constants");
function scanJavaScriptSource(source, ast, context = {}, modelUse = "") {
  const masked = (0, import_source.maskJavaScriptSource)(source);
  const functionRanges = collectScanFunctionRanges(masked, ast);
  const blockRanges = (0, import_source.collectBraceRanges)(masked);
  const staticBlockRanges = (0, import_source.collectStaticBlockRanges)(masked);
  const sourceBindings = (0, import_bindings.collectSourceBindings)(masked, functionRanges, blockRanges, staticBlockRanges);
  const stringLiteralBindings = (0, import_bindings.collectStringLiteralBindings)(source, masked, sourceBindings);
  const astInspection = ast ? inspectRunJsAst(ast, source, stringLiteralBindings, context, modelUse) : void 0;
  const ctxRenderCalls = (0, import_static_values.findUnboundCtxMatches)(masked, /\bctx\s*(?:\?\.|\.)\s*render\s*(?:\?\.)?\(/g, sourceBindings);
  const topLevelCtxRenderCalls = ctxRenderCalls.filter((entry) => !(0, import_source.isInsideRanges)(entry.index, functionRanges));
  const topLevelReachableCtxRenderCalls = astInspection ? (0, import_bindings.dedupeIndexedEntries)(astInspection.topLevelReachableCtxRenderCalls).sort(
    (left, right) => left.index - right.index
  ) : topLevelCtxRenderCalls.map((entry) => ({
    capability: "ctx.render",
    index: entry.index
  }));
  const topLevelReturns = (0, import_source.findMatches)(masked, /\breturn\b/g).filter(
    (entry) => !(0, import_source.isInsideRanges)(entry.index, functionRanges)
  );
  const ctxRunjsCalls = (0, import_static_values.findUnboundCtxMatches)(masked, /\bctx\s*(?:\?\.|\.)\s*runjs\s*(?:\?\.)?\(/g, sourceBindings);
  const ctxRequestCalls = (0, import_static_values.findUnboundCtxMatches)(
    masked,
    /\bctx\s*(?:\?\.|\.)\s*(?:api\s*(?:\?\.|\.)\s*)?request\s*(?:\?\.)?\(/g,
    sourceBindings
  );
  const reactHookCalls = (0, import_source_patterns.collectReactHookCalls)(masked, sourceBindings);
  const reactComponentAliases = (0, import_source_patterns.collectReactComponentAliases)(masked, sourceBindings);
  const flowResourceAliases = (0, import_source_patterns.collectFlowResourceAliases)(masked, sourceBindings);
  const directDomWrites = (0, import_source_patterns.collectDirectDomWrites)(source, masked, sourceBindings);
  const directDomAliases = (0, import_source_patterns.collectDirectDomAliases)(masked, sourceBindings);
  const windowDocumentNavigatorUses = (0, import_source_patterns.collectWindowDocumentNavigatorUses)(source, masked, sourceBindings);
  const windowDocumentNavigatorAliases = (0, import_source_patterns.collectWindowDocumentNavigatorAliases)(masked, sourceBindings);
  const ctxAliases = (0, import_source_patterns.collectCtxAliases)(masked, sourceBindings);
  const forbiddenBareGlobals = (0, import_source_patterns.collectForbiddenBareGlobals)(masked, sourceBindings);
  return {
    source,
    masked,
    functionRanges,
    blockRanges,
    sourceBindings,
    unknownBareGlobals: (astInspection == null ? void 0 : astInspection.unknownBareGlobals) || [],
    ctxRenderCalls,
    topLevelCtxRenderCalls,
    topLevelReachableCtxRenderCalls,
    topLevelReturns,
    ctxRunjsCalls,
    nestedRunjsCalls: (astInspection == null ? void 0 : astInspection.nestedRunjsCalls) || ctxRunjsCalls.map((entry) => ({
      capability: "ctx.runjs",
      index: entry.index
    })),
    invalidReactRuntimeBindings: (astInspection == null ? void 0 : astInspection.invalidReactRuntimeBindings) || [],
    ctxRequestCalls,
    invalidApiResourceCalls: (0, import_bindings.dedupeIndexedEntries)([
      ...(0, import_source_patterns.collectInvalidApiResourceCalls)(source, masked, sourceBindings),
      ...(astInspection == null ? void 0 : astInspection.invalidApiResourceCalls) || []
    ]).sort((left, right) => left.index - right.index),
    invalidResourceActionCalls: (astInspection == null ? void 0 : astInspection.invalidResourceActionCalls) || [],
    invalidResourceTypeCalls: (astInspection == null ? void 0 : astInspection.invalidResourceTypeCalls) || (0, import_source_patterns.collectInvalidResourceTypeCalls)(source, masked, stringLiteralBindings, sourceBindings),
    invalidFlowResourceListCalls: (0, import_bindings.dedupeIndexedEntries)([
      ...(0, import_source_patterns.collectInvalidFlowResourceListCalls)(masked, flowResourceAliases, sourceBindings),
      ...(astInspection == null ? void 0 : astInspection.invalidFlowResourceListCalls) || []
    ]).sort((left, right) => left.index - right.index),
    invalidFlowResourceMethodCalls: (astInspection == null ? void 0 : astInspection.invalidFlowResourceMethodCalls) || [],
    invalidResourceFilterCalls: (astInspection == null ? void 0 : astInspection.invalidResourceFilterCalls) || [],
    resourceCallsInReactHooks: (0, import_source_patterns.collectResourceCallsInReactHooks)(source, masked, reactHookCalls, sourceBindings),
    topLevelReactHookCalls: reactHookCalls.filter((entry) => !(0, import_source.isInsideRanges)(entry.index, functionRanges)),
    unboundReactCreateElementCalls: (0, import_source_patterns.collectUnboundReactCreateElementCalls)(masked, sourceBindings),
    reactComponentFunctionCalls: (0, import_source_patterns.collectReactComponentFunctionCalls)(masked, reactComponentAliases, sourceBindings),
    reactAsyncComponentReferences: (astInspection == null ? void 0 : astInspection.reactAsyncComponentReferences) || [],
    reactComponentCtxRenderCalls: (astInspection == null ? void 0 : astInspection.reactComponentCtxRenderCalls) || [],
    sharedCtxResourceCallsInFunctions: (astInspection == null ? void 0 : astInspection.sharedCtxResourceCallsInFunctions) || [],
    ctxRenderComponentSignatureCalls: (0, import_source_patterns.collectCtxRenderComponentSignatureCalls)(
      source,
      masked,
      reactComponentAliases,
      sourceBindings
    ),
    reactComponentPropReferences: (0, import_source_patterns.collectReactComponentPropReferences)(
      source,
      masked,
      reactComponentAliases,
      sourceBindings
    ),
    directDomWrites,
    directDomAliases,
    windowDocumentNavigatorUses,
    windowDocumentNavigatorAliases,
    ctxAliases,
    ctxLibMemberCaseMismatches: (0, import_source_patterns.collectCtxLibMemberCaseMismatches)(source, masked, sourceBindings),
    invalidCtxApiMemberAccesses: (astInspection == null ? void 0 : astInspection.invalidCtxApiMemberAccesses) || [],
    invalidCtxNonFunctionCalls: (astInspection == null ? void 0 : astInspection.invalidCtxNonFunctionCalls) || [],
    invalidCtxLibMemberAccesses: (astInspection == null ? void 0 : astInspection.invalidCtxLibMemberAccesses) || [],
    forbiddenBareGlobals,
    ctxMemberAccesses: (0, import_source_patterns.collectCtxMemberAccesses)(masked, sourceBindings),
    dynamicCtxAccesses: (0, import_static_values.findUnboundCtxMatches)(masked, /\bctx\s*(?:\?\.\s*)?\[/g, sourceBindings),
    isTopLevelFunctionWrapper: (0, import_source_patterns.isTopLevelFunctionWrapper)(masked, functionRanges, topLevelReachableCtxRenderCalls)
  };
}
function collectScanFunctionRanges(masked, ast) {
  if (!ast) {
    return (0, import_source.findFunctionRanges)(masked);
  }
  const ranges = (0, import_source.collectAstFunctionBodyRanges)(ast);
  (0, import_source.collectArrowExpressionRanges)(masked, ranges);
  return (0, import_source.mergeRanges)(ranges);
}
function collectAstUnknownBareGlobalsFromAst(ast, identifierBindings, modelUse) {
  var _a;
  const allowedGlobals = new Set(import_constants.RUNJS_ALLOWED_BARE_GLOBALS);
  (_a = import_constants.RUNJS_ALLOWED_BARE_GLOBALS_BY_MODEL_USE[modelUse]) == null ? void 0 : _a.forEach((name) => allowedGlobals.add(name));
  const entries = [];
  const reported = /* @__PURE__ */ new Set();
  (0, import_walk.walkAstAncestor)(ast, {
    Identifier(node, ancestors) {
      const name = typeof (node == null ? void 0 : node.name) === "string" ? node.name : "";
      if (!name) {
        return;
      }
      if (allowedGlobals.has(name) || import_constants.FORBIDDEN_BARE_GLOBALS.has(name)) {
        return;
      }
      const index = typeof node.start === "number" ? node.start : 0;
      if (hasAstDeclaredBindingAtIndex(name, index, identifierBindings)) {
        return;
      }
      if (!isIdentifierReadReference(node, ancestors)) {
        return;
      }
      const key = `${name}@${index}`;
      if (reported.has(key)) {
        return;
      }
      reported.add(key);
      entries.push({
        index,
        name,
        suggestedCapability: import_constants.ALLOWED_CTX_ROOTS.has(name) ? `ctx.${name}` : void 0
      });
    }
  });
  return entries.sort((left, right) => left.index - right.index);
}
function hasAstDeclaredBindingAtIndex(name, index, identifierBindings) {
  var _a;
  const binding = (0, import_static_values.resolveAstActiveIdentifierBinding)(name, index, identifierBindings);
  if (!binding) {
    return false;
  }
  if ((_a = binding.unavailableRanges) == null ? void 0 : _a.some((range) => index >= range.start && index < range.end)) {
    return false;
  }
  return index >= (binding.declarationStart ?? binding.start);
}
function isIdentifierReadReference(node, ancestors) {
  const parent = ancestors[ancestors.length - 2];
  const grandparent = ancestors[ancestors.length - 3];
  if (!parent) {
    return true;
  }
  if (parent.type === "VariableDeclarator" && parent.id === node || parent.type === "FunctionDeclaration" && parent.id === node || parent.type === "FunctionExpression" && parent.id === node || parent.type === "ClassDeclaration" && parent.id === node || parent.type === "ClassExpression" && parent.id === node || parent.type === "MethodDefinition" && parent.key === node && parent.computed !== true || parent.type === "PropertyDefinition" && parent.key === node && parent.computed !== true || parent.type === "MemberExpression" && parent.property === node && parent.computed !== true || parent.type === "LabeledStatement" && parent.label === node || parent.type === "BreakStatement" && parent.label === node || parent.type === "ContinueStatement" && parent.label === node || parent.type === "MetaProperty") {
    return false;
  }
  if (parent.type === "Property") {
    if ((grandparent == null ? void 0 : grandparent.type) === "ObjectPattern") {
      return false;
    }
    if (parent.key === node && parent.value !== node && parent.computed !== true) {
      return false;
    }
  }
  return true;
}
function inspectRunJsAst(ast, source, stringBindings, context = {}, modelUse = "") {
  const identifierBindings = (0, import_static_bindings.collectAstIdentifierBindingsFromAst)(ast, source);
  const functionBindings = (0, import_static_bindings.collectAstFunctionBindingsFromAst)(ast, source);
  const aliases = (0, import_ctx_api.collectCtxMethodAliasesFromAst)(ast, source, identifierBindings);
  const ctxRootAliases = (0, import_ctx_api.collectCtxRootAliasesFromAst)(ast, source, identifierBindings);
  const ctxDefiniteRootAliases = (0, import_ctx_api.collectCtxDefiniteRootAliasesFromAst)(ast, source, identifierBindings);
  const ctxNonFunctionRootAliases = (0, import_ctx_api.collectCtxNonFunctionRootAliasesFromAst)(
    ast,
    source,
    ctxDefiniteRootAliases,
    identifierBindings,
    modelUse
  );
  const ctxApiAliases = (0, import_ctx_api.collectCtxApiAliasesFromAst)(ast, source, identifierBindings);
  const ctxLibsRootAliases = (0, import_ctx_api.collectCtxLibsRootAliasesFromAst)(ast, source, identifierBindings);
  const ctxLibAliases = (0, import_ctx_api.collectCtxLibAliasesFromAst)(ast, source, ctxLibsRootAliases, identifierBindings);
  const staticStringBindings = [
    ...stringBindings,
    ...(0, import_static_bindings.collectStaticStringBindingsFromAst)(ast, source, stringBindings, identifierBindings)
  ];
  const staticFilterValueBindings = (0, import_static_bindings.collectStaticFilterValueBindingsFromAst)(ast, source, identifierBindings);
  const ctxApiResourceAliases = (0, import_ctx_api.collectCtxApiResourceAliasesFromAst)(
    ast,
    source,
    ctxApiAliases,
    staticStringBindings,
    staticFilterValueBindings,
    identifierBindings
  );
  const reactNamespaceAliases = (0, import_react.collectReactNamespaceAliasesFromAst)(ast, source, identifierBindings, ctxRootAliases);
  const reactDefaultAliases = (0, import_react.collectReactDefaultAliasesFromAst)(
    ast,
    source,
    identifierBindings,
    reactNamespaceAliases,
    ctxRootAliases
  );
  const invalidReactRuntimeBindings = (0, import_react.collectAstInvalidReactRuntimeBindingsFromAst)(
    ast,
    source,
    identifierBindings,
    reactNamespaceAliases,
    ctxRootAliases,
    reactDefaultAliases
  );
  const reactCreateElementAliases = (0, import_react.collectReactCreateElementAliasesFromAst)(
    ast,
    source,
    identifierBindings,
    reactNamespaceAliases,
    ctxRootAliases
  );
  const asyncComponentBindings = (0, import_react.collectReactAsyncComponentBindingsFromAst)(ast, source, identifierBindings);
  const flowResourceAliases = (0, import_resource.collectAstFlowResourceAliasesFromAst)(
    ast,
    source,
    aliases,
    staticStringBindings,
    identifierBindings
  );
  const nestedRunjsCalls = [];
  const invalidCtxApiMemberAccesses = [
    ...(0, import_ctx_api.collectAstInvalidCtxApiPatternAccesses)(ast, ctxApiAliases, identifierBindings)
  ];
  const invalidCtxNonFunctionCalls = [];
  const invalidCtxLibMemberAccesses = [
    ...(0, import_ctx_api.collectAstInvalidCtxLibPatternAccesses)(ast, ctxLibAliases, ctxLibsRootAliases, identifierBindings, source)
  ];
  const invalidApiResourceCalls = [];
  const invalidResourceActionCalls = (0, import_resource.collectAstInvalidResourceActionCalls)(
    ast,
    source,
    flowResourceAliases,
    identifierBindings,
    aliases,
    ctxApiAliases,
    ctxApiResourceAliases,
    staticStringBindings,
    staticFilterValueBindings,
    context
  );
  const invalidResourceTypeCalls = [];
  const invalidFlowResourceListCalls = [];
  const invalidFlowResourceMethodCalls = [];
  const invalidResourceFilterCalls = (0, import_filter.collectAstInvalidResourceFilterCalls)(
    ast,
    source,
    flowResourceAliases,
    identifierBindings,
    aliases,
    staticStringBindings,
    staticFilterValueBindings,
    context
  );
  const reactAsyncComponentReferences = [];
  const topLevelReachableCtxRenderCalls = (0, import_react_render.collectAstTopLevelReachableCtxRenderCallsFromAst)(
    ast,
    aliases,
    identifierBindings,
    functionBindings
  );
  const reactComponentCtxRenderCalls = (0, import_react_render.collectAstReactComponentCtxRenderCallsFromAst)(
    topLevelReachableCtxRenderCalls,
    aliases,
    reactCreateElementAliases,
    identifierBindings,
    functionBindings
  );
  const sharedCtxResourceCallsInFunctions = (0, import_resource.collectAstSharedCtxResourceCallsInFunctions)(
    ast,
    source,
    aliases,
    identifierBindings
  );
  const unknownBareGlobals = collectAstUnknownBareGlobalsFromAst(ast, identifierBindings, modelUse);
  (0, import_walk.walkAstSimple)(ast, {
    CallExpression(node) {
      const method = (0, import_static_values.resolveCtxMethodCall)(node, aliases, identifierBindings);
      if (method) {
        if (method.method === "runjs") {
          nestedRunjsCalls.push({
            capability: method.capability,
            index: node.start || 0
          });
          return;
        }
        if (method.method === "makeResource" || method.method === "initResource") {
          invalidResourceTypeCalls.push(
            ...(0, import_resource.collectAstInvalidResourceTypeCall)(
              node,
              method.method,
              method.capability,
              source,
              staticStringBindings,
              identifierBindings
            )
          );
        }
      }
      const flowResourceMethodCall = (0, import_resource.collectAstInvalidFlowResourceMethodCall)(
        node,
        flowResourceAliases,
        source,
        identifierBindings,
        aliases,
        staticStringBindings
      );
      flowResourceMethodCall.invalidListCalls.forEach((entry) => invalidFlowResourceListCalls.push(entry));
      flowResourceMethodCall.invalidMethodCalls.forEach((entry) => invalidFlowResourceMethodCalls.push(entry));
      (0, import_ctx_api.collectAstInvalidApiResourceCall)(node, ctxApiAliases, ctxApiResourceAliases, source, identifierBindings).forEach(
        (entry) => invalidApiResourceCalls.push(entry)
      );
      (0, import_ctx_api.collectAstInvalidCtxNonFunctionCall)(
        node,
        ctxDefiniteRootAliases,
        ctxNonFunctionRootAliases,
        identifierBindings,
        modelUse
      ).forEach((entry) => invalidCtxNonFunctionCalls.push(entry));
      (0, import_react.collectAstReactAsyncComponentReferences)(
        node,
        asyncComponentBindings,
        reactCreateElementAliases,
        identifierBindings
      ).forEach((entry) => reactAsyncComponentReferences.push(entry));
    },
    MemberExpression(node) {
      const invalidCtxLibAccess = (0, import_ctx_api.collectAstInvalidCtxLibMemberAccess)(
        node,
        ctxLibAliases,
        ctxLibsRootAliases,
        identifierBindings,
        source
      );
      if (invalidCtxLibAccess) {
        invalidCtxLibMemberAccesses.push(invalidCtxLibAccess);
      }
      const invalidCtxApiAccess = (0, import_ctx_api.collectAstInvalidCtxApiMemberAccess)(node, ctxApiAliases, identifierBindings, source);
      if (invalidCtxApiAccess) {
        invalidCtxApiMemberAccesses.push(invalidCtxApiAccess);
      }
    },
    AssignmentExpression(node) {
      (0, import_ctx_api.collectAstInvalidCtxApiReadonlyWrites)(node.left, ctxApiAliases, identifierBindings).forEach(
        (entry) => invalidCtxApiMemberAccesses.push(entry)
      );
    },
    UpdateExpression(node) {
      (0, import_ctx_api.collectAstInvalidCtxApiReadonlyWrites)(node.argument, ctxApiAliases, identifierBindings).forEach(
        (entry) => invalidCtxApiMemberAccesses.push(entry)
      );
    },
    UnaryExpression(node) {
      if (node.operator !== "delete") {
        return;
      }
      (0, import_ctx_api.collectAstInvalidCtxApiReadonlyWrites)(node.argument, ctxApiAliases, identifierBindings).forEach(
        (entry) => invalidCtxApiMemberAccesses.push(entry)
      );
    },
    ForInStatement(node) {
      (0, import_ctx_api.collectAstInvalidCtxApiReadonlyWrites)(node.left, ctxApiAliases, identifierBindings).forEach(
        (entry) => invalidCtxApiMemberAccesses.push(entry)
      );
    },
    ForOfStatement(node) {
      (0, import_ctx_api.collectAstInvalidCtxApiReadonlyWrites)(node.left, ctxApiAliases, identifierBindings).forEach(
        (entry) => invalidCtxApiMemberAccesses.push(entry)
      );
    }
  });
  const dedupedInvalidApiResourceCalls = (0, import_bindings.dedupeIndexedEntries)(invalidApiResourceCalls).sort(
    (left, right) => left.index - right.index
  );
  return {
    unknownBareGlobals,
    invalidApiResourceCalls: dedupedInvalidApiResourceCalls,
    invalidResourceActionCalls: (0, import_bindings.dedupeIndexedEntries)(invalidResourceActionCalls).sort(
      (left, right) => left.index - right.index
    ),
    invalidCtxApiMemberAccesses: (0, import_ctx_api.filterInvalidCtxApiMemberAccessesForResourceCalls)(
      (0, import_bindings.dedupeIndexedEntries)(invalidCtxApiMemberAccesses),
      dedupedInvalidApiResourceCalls
    ).sort((left, right) => left.index - right.index),
    invalidCtxNonFunctionCalls: (0, import_bindings.dedupeIndexedEntries)(invalidCtxNonFunctionCalls).sort(
      (left, right) => left.index - right.index
    ),
    invalidCtxLibMemberAccesses: (0, import_bindings.dedupeIndexedEntries)(invalidCtxLibMemberAccesses).sort(
      (left, right) => left.index - right.index
    ),
    invalidResourceTypeCalls: (0, import_static_values.dedupeAstResourceEntries)(invalidResourceTypeCalls),
    invalidFlowResourceListCalls: (0, import_bindings.dedupeIndexedEntries)(invalidFlowResourceListCalls).sort(
      (left, right) => left.index - right.index
    ),
    invalidFlowResourceMethodCalls: (0, import_bindings.dedupeIndexedEntries)(invalidFlowResourceMethodCalls).sort(
      (left, right) => left.index - right.index
    ),
    invalidResourceFilterCalls: (0, import_bindings.dedupeIndexedEntries)(invalidResourceFilterCalls).sort(
      (left, right) => left.index - right.index
    ),
    invalidReactRuntimeBindings: (0, import_bindings.dedupeIndexedEntries)(invalidReactRuntimeBindings).sort(
      (left, right) => left.start - right.start
    ),
    nestedRunjsCalls: (0, import_bindings.dedupeIndexedEntries)(nestedRunjsCalls).sort((left, right) => left.index - right.index),
    reactAsyncComponentReferences: (0, import_bindings.dedupeIndexedEntries)(reactAsyncComponentReferences).sort(
      (left, right) => left.index - right.index
    ),
    reactComponentCtxRenderCalls,
    sharedCtxResourceCallsInFunctions,
    topLevelReachableCtxRenderCalls
  };
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  scanJavaScriptSource
});
