"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/search-indexer.ts
var search_indexer_exports = {};
__export(search_indexer_exports, {
  buildSearchIndex: () => buildSearchIndex,
  collectSearchRecords: () => collectSearchRecords,
  markdownToSearchText: () => markdownToSearchText
});
module.exports = __toCommonJS(search_indexer_exports);
var import_promises = __toESM(require("fs/promises"), 1);
var import_node_path = __toESM(require("path"), 1);
var import_glob = require("glob");
var import_gray_matter = __toESM(require("gray-matter"), 1);
var RESOURCE_COLLECTIONS = {
  adrs: { docsPath: "adrs", type: "Architecture Decision" },
  agents: { docsPath: "agents", type: "Agent" },
  channels: { docsPath: "channels", type: "Channel" },
  commands: { docsPath: "commands", type: "Command" },
  containers: { docsPath: "containers", type: "Container" },
  "data-products": { docsPath: "data-products", type: "Data Product" },
  domains: { docsPath: "domains", type: "Domain" },
  entities: { docsPath: "entities", type: "Entity" },
  events: { docsPath: "events", type: "Event" },
  flows: { docsPath: "flows", type: "Flow" },
  queries: { docsPath: "queries", type: "Query" },
  services: { docsPath: "services", type: "Service" },
  subdomains: { docsPath: "domains", type: "Domain" }
};
var IGNORED_GLOBS = [
  "**/.git/**",
  "**/.eventcatalog-core/**",
  "**/dist/**",
  "**/node_modules/**",
  "**/public/**",
  "**/snippets/**",
  "**/chat-prompts/**"
];
var trimSlashes = (value) => value.replace(/^\/+|\/+$/g, "");
var normalizePath = (value) => value.replace(/\\/g, "/");
var removeExtension = (value) => value.replace(/\.(md|mdx)$/i, "");
var stripNumericPrefix = (value) => value.replace(/^\d+(?:[-_.\s]+)?/, "") || value;
var normalizeUrlPath = (value) => {
  const withoutIndex = value.replace(/\/index$/i, "");
  return withoutIndex || "";
};
var buildUrl = (pathname, config) => {
  const base = config.base ? `/${trimSlashes(config.base)}` : "";
  const cleanPath = `/${trimSlashes(pathname)}`;
  const url = `${base}${cleanPath}`.replace(/\/{2,}/g, "/");
  if (config.trailingSlash === true && !url.endsWith("/")) {
    return `${url}/`;
  }
  return url || "/";
};
var valueToSearchText = (value) => {
  if (value === null || value === void 0) return "";
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return String(value);
  if (Array.isArray(value)) return value.map(valueToSearchText).filter(Boolean).join(" ");
  if (typeof value === "object") return Object.values(value).map(valueToSearchText).filter(Boolean).join(" ");
  return "";
};
var markdownToSearchText = (content) => {
  return content.replace(/<!--[\s\S]*?-->/g, " ").replace(/^\s*import\s+.*$/gm, " ").replace(/^\s*export\s+.*$/gm, " ").replace(/```[\s\S]*?```/g, (match) => match.replace(/```[a-zA-Z0-9-]*\n?/g, " ").replace(/```/g, " ")).replace(/<([A-Z][A-Za-z0-9.]*)\b([^>]*)\/?>/g, (_match, _component, attributes) => {
    const quotedValues = [...String(attributes).matchAll(/(?:title|label|description|alt|summary)=["'`]([^"'`]+)["'`]/g)];
    return quotedValues.map((entry) => entry[1]).join(" ");
  }).replace(/<\/?[A-Za-z][^>]*>/g, " ").replace(/\[\[([^|\]]+)\|([^\]]+)\]\]/g, "$2").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/[`*_~>#|{}[\]():]/g, " ").replace(/\s+/g, " ").trim();
};
var inferDocIdFromFile = (relativePath, frontmatterId) => {
  if (frontmatterId) return frontmatterId;
  const fileName = import_node_path.default.posix.basename(removeExtension(relativePath));
  if (fileName.toLowerCase() === "index") {
    return import_node_path.default.posix.basename(import_node_path.default.posix.dirname(relativePath));
  }
  return stripNumericPrefix(fileName);
};
var findResourceSegment = (segments) => {
  let match = null;
  for (let index = 0; index < segments.length - 1; index++) {
    const segment = segments[index];
    if (segments[index - 1] === "docs") {
      continue;
    }
    if (RESOURCE_COLLECTIONS[segment] && segments[index + 1]) {
      match = { index, segment };
    }
  }
  return match;
};
var readResourceFrontmatter = async (projectDir, resourcePath) => {
  const candidates = [import_node_path.default.join(projectDir, resourcePath, "index.mdx"), import_node_path.default.join(projectDir, resourcePath, "index.md")];
  for (const candidate of candidates) {
    try {
      const file = await import_promises.default.readFile(candidate, "utf8");
      return (0, import_gray_matter.default)(file).data;
    } catch {
    }
  }
  return {};
};
var deriveRecordFromPath = async ({
  projectDir,
  relativePath,
  data,
  config
}) => {
  const normalizedRelativePath = normalizePath(relativePath);
  const segments = normalizedRelativePath.split("/").filter(Boolean);
  const fileName = segments[segments.length - 1] || "";
  const fileNameWithoutExtension = removeExtension(fileName);
  if (data.hidden === true || data.draft) {
    return null;
  }
  if (segments[0] === "docs") {
    const customPath = normalizeUrlPath(removeExtension(segments.slice(1).join("/")));
    const title = data.title || data.label || import_node_path.default.posix.basename(customPath) || "Custom docs";
    return {
      url: buildUrl(`/docs/custom/${customPath}`, config),
      title,
      summary: data.summary,
      type: "Custom Doc",
      collection: "custom-docs",
      id: customPath
    };
  }
  if (segments[0] === "users" || segments[0] === "teams") {
    const id = data.id || (fileNameWithoutExtension === "index" ? segments[1] : fileNameWithoutExtension);
    const type = segments[0] === "users" ? "User" : "Team";
    return {
      url: buildUrl(`/docs/${segments[0]}/${id}`, config),
      title: data.name || data.title || id,
      summary: data.summary,
      type,
      collection: segments[0],
      id
    };
  }
  const resourceMatch = findResourceSegment(segments);
  if (!resourceMatch) {
    return null;
  }
  const resourceConfig = RESOURCE_COLLECTIONS[resourceMatch.segment];
  const resourceFolderId = segments[resourceMatch.index + 1];
  const resourcePathSegments = segments.slice(0, resourceMatch.index + 2);
  const versionFromPath = segments[resourceMatch.index + 2] === "versioned" && segments[resourceMatch.index + 3] ? segments[resourceMatch.index + 3] : void 0;
  if (versionFromPath) {
    resourcePathSegments.push("versioned", versionFromPath);
  }
  const resourcePath = resourcePathSegments.join("/");
  const resourceData = fileNameWithoutExtension === "index" ? data : await readResourceFrontmatter(projectDir, resourcePath);
  const resourceId = resourceData.id || data.resourceId || resourceFolderId;
  const resourceVersion = versionFromPath || resourceData.version || data.resourceVersion || data.version;
  if (!resourceVersion) {
    return null;
  }
  if (fileNameWithoutExtension === "index") {
    return {
      url: buildUrl(`/docs/${resourceConfig.docsPath}/${resourceId}/${resourceVersion}`, config),
      title: data.name || data.title || resourceId,
      summary: data.summary,
      type: resourceConfig.type,
      collection: resourceConfig.docsPath,
      id: resourceId,
      version: resourceVersion
    };
  }
  if (fileNameWithoutExtension === "ubiquitous-language") {
    return {
      url: buildUrl(`/docs/${resourceConfig.docsPath}/${resourceId}/language`, config),
      title: data.title || `${resourceData.name || resourceId} ubiquitous language`,
      summary: data.summary,
      type: "Language",
      collection: "language",
      id: resourceId,
      version: resourceVersion
    };
  }
  if (fileNameWithoutExtension === "changelog") {
    return {
      url: buildUrl(`/docs/${resourceConfig.docsPath}/${resourceId}/${resourceVersion}/changelog`, config),
      title: data.title || `${resourceData.name || resourceId} changelog`,
      summary: data.summary,
      type: "Changelog",
      collection: "changelog",
      id: resourceId,
      version: resourceVersion
    };
  }
  const docsIndex = segments.indexOf("docs");
  if (docsIndex > resourceMatch.index) {
    const docType = data.type || segments[docsIndex + 1] || "pages";
    const docId = inferDocIdFromFile(normalizedRelativePath, data.id);
    const title = data.title || stripNumericPrefix(removeExtension(fileName));
    return {
      url: buildUrl(`/docs/${resourceConfig.docsPath}/${resourceId}/${resourceVersion}/${docType}/${docId}`, config),
      title,
      summary: data.summary,
      type: "Resource Doc",
      collection: docType,
      id: docId,
      version: data.version || resourceVersion
    };
  }
  if (segments[0] === "diagrams") {
    const id = data.id || resourceFolderId;
    const version = data.version || resourceVersion;
    return {
      url: buildUrl(`/diagrams/${id}/${version}`, config),
      title: data.name || data.title || id,
      summary: data.summary,
      type: "Design",
      collection: "diagrams",
      id,
      version
    };
  }
  return null;
};
var collectSearchRecords = async ({
  projectDir,
  config
}) => {
  const files = await (0, import_glob.glob)("**/*.{md,mdx}", {
    cwd: projectDir,
    absolute: true,
    nodir: true,
    ignore: IGNORED_GLOBS,
    windowsPathsNoEscape: process.platform === "win32"
  });
  const records = await Promise.all(
    files.map(async (file) => {
      const raw = await import_promises.default.readFile(file, "utf8");
      const parsed = (0, import_gray_matter.default)(raw);
      const relativePath = normalizePath(import_node_path.default.relative(projectDir, file));
      const baseRecord = await deriveRecordFromPath({
        projectDir,
        relativePath,
        data: parsed.data,
        config
      });
      if (!baseRecord) {
        return null;
      }
      const frontmatterText = valueToSearchText({
        id: baseRecord.id,
        title: baseRecord.title,
        summary: baseRecord.summary,
        version: baseRecord.version,
        owners: parsed.data.owners,
        status: parsed.data.status,
        date: parsed.data.date,
        decisionMakers: parsed.data.decisionMakers,
        appliesTo: parsed.data.appliesTo,
        badges: parsed.data.badges
      });
      const content = [frontmatterText, markdownToSearchText(parsed.content)].filter(Boolean).join("\n\n");
      if (!content.trim()) {
        return null;
      }
      return {
        ...baseRecord,
        content
      };
    })
  );
  const uniqueRecords = /* @__PURE__ */ new Map();
  for (const record of records) {
    if (!record) continue;
    uniqueRecords.set(record.url, record);
  }
  return [...uniqueRecords.values()].sort((a, b) => a.url.localeCompare(b.url));
};
var getSearchOutputPath = ({
  outDir,
  isServer,
  searchOutputPath
}) => {
  if (searchOutputPath) {
    return searchOutputPath;
  }
  return import_node_path.default.join(outDir, isServer ? "client" : "", "pagefind");
};
var buildSearchIndex = async ({ projectDir, outDir, config, isServer, searchOutputPath }) => {
  const records = await collectSearchRecords({ projectDir, config });
  if (records.length === 0) {
    throw new Error("No searchable Markdown or MDX content was found.");
  }
  const pagefind = await import("pagefind");
  const { index } = await pagefind.createIndex({
    keepIndexUrl: false,
    writePlayground: false
  });
  const errors = [];
  for (const record of records) {
    const result = await index.addCustomRecord({
      url: record.url,
      content: record.content,
      language: "en",
      meta: {
        title: record.title,
        summary: record.summary || "",
        type: record.type,
        collection: record.collection,
        id: record.id || "",
        version: record.version || ""
      },
      filters: {
        type: [record.type],
        collection: [record.collection]
      }
    });
    if (result.errors?.length) {
      errors.push(...result.errors.map((error) => `${record.url}: ${error.message || error}`));
    }
  }
  const outputPath = getSearchOutputPath({ outDir, isServer, searchOutputPath });
  await import_promises.default.rm(outputPath, { recursive: true, force: true });
  const writeResult = await index.writeFiles({ outputPath });
  if (writeResult.errors?.length) {
    errors.push(...writeResult.errors.map((error) => error.message || String(error)));
  }
  await index.deleteIndex?.();
  await pagefind.close?.();
  if (errors.length > 0) {
    throw new Error(`Failed to build indexed search:
${errors.join("\n")}`);
  }
  return {
    records: records.length,
    outputPath
  };
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  buildSearchIndex,
  collectSearchRecords,
  markdownToSearchText
});
