// src/actions/dead/ruleConfig.ts
var VALID_RULE_LEVELS = /* @__PURE__ */ new Set(["off", "warn", "error"]);
function isRecord(value) {
  return typeof value === "object" && value !== null && !Array.isArray(value);
}
function isRuleLevel(value) {
  return typeof value === "string" && VALID_RULE_LEVELS.has(value);
}
function severityFromLevel(level) {
  return level === "warn" ? "warning" : "error";
}
function formatRuleConfigLocation(ruleId) {
  return `commands.dead.rules["${ruleId}"]`;
}
function parseRuleConfig(ruleId, value) {
  if (typeof value === "string") {
    if (!isRuleLevel(value)) {
      throw new TypeError(`${formatRuleConfigLocation(ruleId)} must be one of "off", "warn", or "error"`);
    }
    return { level: value, options: {} };
  }
  if (Array.isArray(value)) {
    if (value.length !== 2) {
      throw new TypeError(`${formatRuleConfigLocation(ruleId)} tuple must be [level, options]`);
    }
    const level = value[0];
    if (!isRuleLevel(level)) {
      throw new TypeError(`${formatRuleConfigLocation(ruleId)} level must be one of "off", "warn", or "error"`);
    }
    const options = value[1];
    if (!isRecord(options)) {
      throw new TypeError(`${formatRuleConfigLocation(ruleId)} options must be an object`);
    }
    return { level, options: { ...options } };
  }
  if (isRecord(value)) {
    return { level: "warn", options: { ...value } };
  }
  throw new TypeError(`${formatRuleConfigLocation(ruleId)} must be a level, options object, or [level, options] tuple`);
}
function validateIgnore(ruleId, options) {
  if (options.ignore === void 0) return;
  if (!Array.isArray(options.ignore) || options.ignore.some((pattern) => typeof pattern !== "string")) {
    throw new TypeError(`${formatRuleConfigLocation(ruleId)}.ignore must be an array of strings`);
  }
}
function validateOptions(ruleId, options) {
  validateIgnore(ruleId, options);
  for (const key of Object.keys(options)) {
    if (key !== "ignore") {
      throw new TypeError(`${formatRuleConfigLocation(ruleId)} has unknown option "${key}"`);
    }
  }
}
function normalizeDeadRules(rules, config) {
  const ruleConfigs = config?.rules ?? {};
  const ruleIds = new Set(rules.map((rule) => rule.id));
  const unknownRuleIds = Object.keys(ruleConfigs).filter((ruleId) => !ruleIds.has(ruleId));
  if (unknownRuleIds.length > 0) {
    throw new TypeError(`Unknown dead rule ${unknownRuleIds.map((ruleId) => `"${ruleId}"`).join(", ")} in commands.dead.rules`);
  }
  return rules.map((rule) => {
    const ruleConfig = ruleConfigs[rule.id];
    if (ruleConfig === void 0) {
      return {
        ...rule,
        enabled: rule.enabled,
        meta: {
          ...rule.meta,
          severity: rule.enabled ? rule.meta.severity ?? "warning" : void 0
        },
        options: {}
      };
    }
    const { level, options } = parseRuleConfig(rule.id, ruleConfig);
    validateOptions(rule.id, options);
    return {
      ...rule,
      enabled: level !== "off",
      meta: level === "off" ? { ...rule.meta } : { ...rule.meta, severity: severityFromLevel(level) },
      options
    };
  });
}

// src/actions/dead/rules.ts
var DEAD_RULES = [
  {
    appliesToVisibility: void 0,
    enabled: true,
    id: "dead.package.internal",
    meta: {
      description: "Declarations that are neither referenced in the package nor part of its public export surface",
      scope: "package",
      severity: "warning"
    },
    options: {}
  },
  {
    appliesToVisibility: void 0,
    enabled: true,
    id: "dead.repo.internal",
    meta: {
      description: "Declarations that are neither referenced anywhere in the monorepo nor part of the public export surface",
      scope: "repo",
      severity: "warning"
    },
    options: {}
  },
  {
    appliesToVisibility: ["private"],
    enabled: true,
    id: "dead.repo.export",
    meta: {
      description: "Public exports of private packages that no other monorepo package imports",
      scope: "repo",
      severity: "warning"
    },
    options: {}
  },
  {
    appliesToVisibility: ["restricted"],
    enabled: true,
    id: "dead.workspace.export",
    meta: {
      description: "Public exports of restricted or scoped packages that no other folder in the VS Code workspace imports",
      scope: "workspace",
      severity: "warning"
    },
    options: {},
    requiresCodeWorkspace: true
  },
  {
    appliesToVisibility: ["public"],
    enabled: false,
    id: "dead.workspace.export-published",
    meta: {
      description: "Public exports of explicitly public packages that no other folder in the VS Code workspace imports",
      scope: "workspace",
      severity: "warning"
    },
    options: {},
    requiresCodeWorkspace: true
  }
];
function loadDeadRules(config) {
  return normalizeDeadRules(DEAD_RULES, config);
}
export {
  DEAD_RULES,
  loadDeadRules
};
//# sourceMappingURL=rules.mjs.map
