// src/actions/package/compile/packageCompileTsc.ts
import { cwd as cwd2 } from "node:process";
import chalk from "chalk";
import ts2, {
  DiagnosticCategory,
  formatDiagnosticsWithColorAndContext,
  getPreEmitDiagnostics,
  sys
} from "typescript";

// src/lib/deepMerge.ts
var UNSAFE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
function isPlainObject(value) {
  if (typeof value !== "object" || value === null) return false;
  const proto = Object.getPrototypeOf(value);
  return proto === Object.prototype || proto === null;
}
function isMergeable(value) {
  return Array.isArray(value) || isPlainObject(value);
}
function cloneValue(value) {
  if (Array.isArray(value)) {
    return value.map((item) => cloneValue(item));
  }
  if (isPlainObject(value)) {
    const result = {};
    for (const [key, item] of Object.entries(value)) {
      if (UNSAFE_KEYS.has(key)) continue;
      result[key] = cloneValue(item);
    }
    return result;
  }
  return value;
}
function mergeObject(target, source, options) {
  const destination = {};
  if (isPlainObject(target)) {
    for (const [key, item] of Object.entries(target)) {
      if (UNSAFE_KEYS.has(key)) continue;
      destination[key] = cloneValue(item);
    }
  }
  for (const [key, sourceValue] of Object.entries(source)) {
    if (UNSAFE_KEYS.has(key)) continue;
    if (Object.hasOwn(target, key) && isMergeable(sourceValue)) {
      const customMerge = options.customMerge?.(key);
      destination[key] = (customMerge ?? deepMerge)(target[key], sourceValue, options);
    } else {
      destination[key] = cloneValue(sourceValue);
    }
  }
  return destination;
}
function deepMerge(target, source, options = {}) {
  const isSourceIsArray = Array.isArray(source);
  const isTargetIsArray = Array.isArray(target);
  if (isSourceIsArray !== isTargetIsArray) {
    return cloneValue(source);
  }
  if (isSourceIsArray) {
    return [...target, ...source].map((item) => cloneValue(item));
  }
  return mergeObject(target, source, options);
}

// src/lib/reporting/xyReporter.ts
var reporterState = {
  currentCommand: "unknown",
  isEnvelopeEmitted: false,
  isJsonModeEnabled: false,
  isStrictModeEnabled: false,
  originalStdoutWrite: void 0,
  startTime: 0
};
function isStrictMode() {
  return reporterState.isStrictModeEnabled || process.env.XY_STRICT === "1";
}

// src/actions/package/compile/createProgramFromConfig.ts
import ts from "typescript";
function createProgramFromConfig(options) {
  const {
    basePath,
    compilerOptions,
    configFilePath,
    exclude,
    files,
    include
  } = options;
  const readResult = ts.readConfigFile(configFilePath, (fileName) => ts.sys.readFile(fileName));
  if (readResult.error) {
    throw new Error(ts.flattenDiagnosticMessageText(readResult.error.messageText, "\n"));
  }
  const config = readResult.config ?? {};
  config.compilerOptions = { ...config.compilerOptions, ...compilerOptions };
  if (include) config.include = include;
  if (files) config.files = files;
  if (exclude) config.exclude = exclude;
  const parsed = ts.parseJsonConfigFileContent(config, ts.sys, basePath, void 0, configFilePath);
  return ts.createProgram({
    configFileParsingDiagnostics: parsed.errors,
    options: parsed.options,
    projectReferences: parsed.projectReferences,
    rootNames: parsed.fileNames
  });
}

// src/actions/package/compile/getCompilerOptions.ts
import { cwd } from "node:process";
import { getTsconfig } from "get-tsconfig";
var getCompilerOptions = (options = {}, fileName = "tsconfig.json") => {
  const resolvedTsConfigCompilerOptions = getTsconfig(cwd(), fileName)?.config?.compilerOptions ?? {};
  return deepMerge(resolvedTsConfigCompilerOptions, options);
};

// src/actions/package/compile/packageCompileTsc.ts
var packageCompileTsc = (platform, entries, srcDir = "src", outDir = "dist", compilerOptionsParam, isVerbose = false) => {
  const pkg = cwd2();
  if (isVerbose) {
    console.log(chalk.cyan(`Validating code START: ${entries.length} files to ${outDir} from ${srcDir}`));
  }
  const configFilePath = ts2.findConfigFile(
    pkg,
    (fileName) => ts2.sys.fileExists(fileName),
    "tsconfig.json"
  );
  if (configFilePath === void 0) {
    throw new Error("Could not find tsconfig.json");
  }
  const compilerOptions = {
    ...getCompilerOptions({
      removeComments: false,
      skipDefaultLibCheck: true,
      skipLibCheck: true,
      sourceMap: false
    }),
    ...compilerOptionsParam,
    outDir: `${outDir}/${platform}`,
    emitDeclarationOnly: true,
    noEmit: false
  };
  console.log(chalk.cyan(`Validating Files: ${entries.length}`));
  if (isVerbose) {
    for (const entry of entries) {
      console.log(chalk.grey(`Validating: ${entry}`));
    }
  }
  try {
    if (entries.length > 0) {
      const program = createProgramFromConfig({
        configFilePath,
        basePath: pkg,
        compilerOptions,
        files: entries.map((entry) => `${srcDir}/${entry}`),
        include: [`${srcDir}/**/*.*`]
      });
      const diagnostics = getPreEmitDiagnostics(program);
      if (diagnostics.length > 0) {
        const formattedDiagnostics = formatDiagnosticsWithColorAndContext(
          diagnostics,
          {
            getCanonicalFileName: (fileName) => fileName,
            getCurrentDirectory: () => srcDir,
            getNewLine: () => sys.newLine
          }
        );
        console.error(formattedDiagnostics);
      }
      const nonEmitPatterns = [".stories.", "/stories/", "/stories.", ".spec.", "/spec/", "/spec.", ".example."];
      program.emit(void 0, (fileName, text, writeByteOrderMark) => {
        if (nonEmitPatterns.some((pattern) => fileName.includes(pattern))) {
          return;
        }
        ts2.sys.writeFile(fileName, text, writeByteOrderMark);
      });
      const isStrict = isStrictMode();
      let count = 0;
      for (const diag of diagnostics) {
        if (diag.category === DiagnosticCategory.Error) {
          count++;
        } else if (isStrict && diag.category === DiagnosticCategory.Warning) {
          count++;
        }
      }
      return count;
    }
    return 0;
  } finally {
    if (isVerbose) {
      console.log(chalk.cyan(`Validating code FINISH: ${entries.length} files to ${outDir} from ${srcDir}`));
    }
  }
};
export {
  packageCompileTsc
};
//# sourceMappingURL=packageCompileTsc.mjs.map
