var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
    var useValue = arguments.length > 2;
    for (var i = 0; i < initializers.length; i++) {
        value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
    }
    return useValue ? value : void 0;
};
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
    function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
    var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
    var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
    var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
    var _, done = false;
    for (var i = decorators.length - 1; i >= 0; i--) {
        var context = {};
        for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
        for (var p in contextIn.access) context.access[p] = contextIn.access[p];
        context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
        var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
        if (kind === "accessor") {
            if (result === void 0) continue;
            if (result === null || typeof result !== "object") throw new TypeError("Object expected");
            if (_ = accept(result.get)) descriptor.get = _;
            if (_ = accept(result.set)) descriptor.set = _;
            if (_ = accept(result.init)) initializers.unshift(_);
        }
        else if (_ = accept(result)) {
            if (kind === "field") initializers.unshift(_);
            else descriptor[key] = _;
        }
    }
    if (target) Object.defineProperty(target, contextIn.name, descriptor);
    done = true;
};
import path from "node:path";
import { stripIndent } from "common-tags";
import { ESLint } from "eslint";
import { getLogger } from "../../util/logger.js";
import llmobs from "../llmobs/index.js";
const options = (cwd) => stripIndent `
  import path from "node:path";

  export default {
    cwd: ${JSON.stringify(cwd)},
    concurrency: "auto",
    cache: true,
    cacheLocation: path.join(${JSON.stringify(cwd)}, ".superblocks", "eslint.cache"),
    fixTypes: ["problem"],
    ignorePatterns: ["apis/**"],
    errorOnUnmatchedPattern: false,
    // NOTE: we are only applying this single rule for now
    // add more rules as they are validated
    ruleFilter: ({ ruleId }) => {
      // TODO: Figure out how to handle later, but don't block ai for now. Omar is working on a fix now.
      // if (ruleId === "superblocks/no-computed-jsx-child") {
      //   return true;
      // }
      if (ruleId === "superblocks/no-duplicate-names") {
        return true;
      }

      return false;
    },
  };
`;
let Linter = (() => {
    let _instanceExtraInitializers = [];
    let _warmCache_decorators;
    let _lint_decorators;
    return class Linter {
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
            _warmCache_decorators = [llmobs.decorate({ kind: "task", name: "Linter.warmCache" })];
            _lint_decorators = [llmobs.decorate({ kind: "task", name: "Linter.lint" })];
            __esDecorate(this, null, _warmCache_decorators, { kind: "method", name: "warmCache", static: false, private: false, access: { has: obj => "warmCache" in obj, get: obj => obj.warmCache }, metadata: _metadata }, null, _instanceExtraInitializers);
            __esDecorate(this, null, _lint_decorators, { kind: "method", name: "lint", static: false, private: false, access: { has: obj => "lint" in obj, get: obj => obj.lint }, metadata: _metadata }, null, _instanceExtraInitializers);
            if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        eslint = __runInitializers(this, _instanceExtraInitializers);
        cwd;
        constructor(cwd) {
            this.cwd = cwd;
            const optionsUrl = new URL(`data:text/javascript,${encodeURIComponent(options(cwd))}`);
            this.eslint = ESLint.fromOptionsModule(optionsUrl);
        }
        async warmCache(files) {
            const eslint = await this.eslint;
            void eslint.lintFiles(files);
        }
        async lint(files, abortSignal) {
            if (abortSignal?.aborted) {
                throw new Error("Operation was aborted");
            }
            const start = performance.now();
            const eslint = await this.eslint;
            const lintWithAbort = async () => {
                return new Promise((resolve, reject) => {
                    if (abortSignal?.aborted) {
                        reject(new Error("Operation was aborted"));
                        return;
                    }
                    const abortHandler = () => {
                        reject(new Error("Operation was aborted"));
                    };
                    abortSignal?.addEventListener("abort", abortHandler);
                    eslint
                        .lintFiles(files)
                        .then(resolve)
                        .catch(reject)
                        .finally(() => {
                        abortSignal?.removeEventListener("abort", abortHandler);
                    });
                });
            };
            const results = await lintWithAbort();
            if (abortSignal?.aborted) {
                throw new Error("Operation was aborted");
            }
            // Track which files were auto-fixed (have output)
            const fixedFiles = results
                .filter((r) => r.output !== undefined)
                .map((r) => path.relative(this.cwd, r.filePath));
            await ESLint.outputFixes(results);
            const errors = results.reduce((acc, result) => {
                const relativePath = path.relative(this.cwd, result.filePath);
                const errorMessages = result.messages
                    .filter((message) => !message.fix)
                    .map((m) => `${relativePath}(${m.line},${m.column}): ${m.message} (${m.ruleId})`);
                if (errorMessages.length > 0) {
                    acc[relativePath] = errorMessages;
                }
                return acc;
            }, {});
            const end = performance.now();
            getLogger().debug(`[ai-service] Linting took ${end - start}ms for ${files.length} files, ${fixedFiles.length} auto-fixed`);
            return { errors, fixedFiles };
        }
    };
})();
export { Linter };
//# sourceMappingURL=linter.js.map