"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.MDXDependencyDetector = void 0;
exports.detectImportsWithRegex = detectImportsWithRegex;
function _mdx() {
  const data = require("@mdx-js/mdx");
  _mdx = function () {
    return data;
  };
  return data;
}
function _mdxModules() {
  const data = require("@teambit/mdx.modules.mdx-v3-options");
  _mdxModules = function () {
    return data;
  };
  return data;
}
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
/**
 * MDX options for dependency detection only.
 * Uses the remark plugins from mdxOptions (for frontmatter and import extraction)
 * but excludes rehype plugins like rehypeMdxCodeProps that fail on legacy
 * code fence meta syntax (e.g. `live=true`).
 */
const detectorMdxOptions = {
  remarkPlugins: _mdxModules().mdxOptions.remarkPlugins,
  jsxImportSource: _mdxModules().mdxOptions.jsxImportSource
};

/**
 * Regex pattern for matching import statements in JavaScript/TypeScript.
 *
 * Structure: /import\s+(?:PATTERN_A|PATTERN_B)/g
 *   - The `import\s+` prefix is OUTSIDE the alternation, so both patterns require the import keyword
 *
 * This regex matches two import patterns in an alternation:
 *
 * PATTERN_A (captured in group 1): [type] <specifiers> from "module"
 *   - Optional "type" keyword for TypeScript type imports
 *   - Specifiers can be: default (x), named ({x}), namespace (* as x), or mixed (x, {y})
 *   - Followed by the `from` keyword and quoted module path
 *   - Module path is captured in group 1
 *
 * PATTERN_B (captured in group 2): "module"
 *   - Side-effect only imports with no specifiers, just quoted module path
 *   - The quotes directly follow `import` with only whitespace in between
 *   - Module path is captured in group 2
 *   - Note: This will NOT match random quoted strings in code (e.g., const x = "foo")
 *     because the `import\s+` prefix is required
 *
 * Example matches:
 *   import x from "y" -> group 1: "y"
 *   import { x } from "y" -> group 1: "y"
 *   import * as x from "y" -> group 1: "y"
 *   import x, { y } from "z" -> group 1: "z"
 *   import type { T } from "y" -> group 1: "y"
 *   import "y" -> group 2: "y"
 *
 * Limitations:
 *   - Will match imports in comments (e.g., // import "x")
 *   - Will match imports in code blocks/strings if they appear to be syntactically valid
 *   - These are acceptable trade-offs for the fallback mode
 */
const IMPORT_STATEMENT_REGEX = /import\s+(?:(?:type\s+)?(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)(?:\s*,\s*\{[^}]*\}|\s*,\s*\w+)?\s+from\s+['"]([^'"]+)['"]|['"]([^'"]+)['"])/g;

/**
 * Regex-based fallback for extracting import sources from MDX files.
 * Used when compileSync fails due to MDX v3 syntax incompatibilities in user content
 * (e.g. HTML comments, escaped characters, bare variable declarations, unclosed tags).
 *
 * Matches both standard imports (import x from "y") and side-effect imports (import "y").
 */
function detectImportsWithRegex(source) {
  const modules = [];
  let match;
  // Reset regex state before use
  IMPORT_STATEMENT_REGEX.lastIndex = 0;
  while ((match = IMPORT_STATEMENT_REGEX.exec(source)) !== null) {
    // Use whichever capture group matched (group 1 for "from" imports, group 2 for side-effect imports)
    const moduleName = match[1] || match[2];
    if (moduleName) modules.push(moduleName);
  }
  return modules;
}
class MDXDependencyDetector {
  constructor(supportedExtensions, logger) {
    this.supportedExtensions = supportedExtensions;
    _defineProperty(this, "logger", void 0);
    _defineProperty(this, "currentFilename", void 0);
    this.logger = logger;
    // Bind methods to preserve `this` context when called as detached functions.
    this.detect = this.detect.bind(this);
    this.isSupported = this.isSupported.bind(this);
  }
  isSupported(context) {
    // Capture filename for use in detect() warning messages.
    // isSupported is always called immediately before detect() for the same file.
    this.currentFilename = context.filename;
    return this.supportedExtensions.includes(context.ext);
  }
  detect(source) {
    const filename = this.currentFilename;
    try {
      var _output$data;
      const output = (0, _mdx().compileSync)(source, detectorMdxOptions);
      const imports = ((_output$data = output.data) === null || _output$data === void 0 ? void 0 : _output$data.imports) || [];
      if (!imports.length) return [];
      return imports.map(importSpec => importSpec.fromModule);
    } catch (err) {
      var _this$logger;
      // MDX v3 may fail to compile files with legacy syntax (HTML comments, escaped
      // characters in prose, bare variable declarations, unclosed tags, etc.).
      // Fall back to regex-based import detection which is sufficient for dependency resolution.
      const fileRef = filename ? ` File: ${filename}` : '';
      const msg = `MDX compilation failed, falling back to regex-based import detection.${fileRef} Error: ${err.message}`;
      (_this$logger = this.logger) === null || _this$logger === void 0 || _this$logger.consoleWarning(msg);
      return detectImportsWithRegex(source);
    }
  }
}
exports.MDXDependencyDetector = MDXDependencyDetector;

//# sourceMappingURL=mdx.detector.js.map