'use strict';

var chunk4MM4BJX6_cjs = require('./chunk-4MM4BJX6.cjs');
var chunkYRPB2JS5_cjs = require('./chunk-YRPB2JS5.cjs');
var chunkZW7CBT5E_cjs = require('./chunk-ZW7CBT5E.cjs');
var chunkB3D7OHHL_cjs = require('./chunk-B3D7OHHL.cjs');
var chunkNAJ36BYA_cjs = require('./chunk-NAJ36BYA.cjs');
var chunkXSCSXEQC_cjs = require('./chunk-XSCSXEQC.cjs');
var chunkHWXKNSQT_cjs = require('./chunk-HWXKNSQT.cjs');
var chunkAF3E2D32_cjs = require('./chunk-AF3E2D32.cjs');
var typeCompiler = require('@deepkit/type-compiler');
var types = require('@storm-software/config-tools/types');
var readFile = require('@stryke/fs/read-file');
var hash = require('@stryke/hash/hash');
var joinPaths = require('@stryke/path/join-paths');
var ts = require('typescript');

function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }

var ts__default = /*#__PURE__*/_interopDefault(ts);

var Compiler = class {
  static {
    chunkAF3E2D32_cjs.__name(this, "Compiler");
  }
  #cache = /* @__PURE__ */ new WeakMap();
  #options;
  /**
  * The logger function to use
  */
  log;
  /**
  * The cache directory
  */
  cacheDir;
  constructor(context, options = {}) {
    this.log = chunkHWXKNSQT_cjs.createLog("compiler", context.options);
    this.#options = options;
    this.cacheDir = joinPaths.joinPaths(context.envPaths.cache, hash.hash(context.tsconfig.options));
  }
  /**
  * Transpile the module.
  *
  * @param context - The compiler context.
  * @param id - The name of the file to compile.
  * @param code - The source code to compile.
  * @returns The transpiled module.
  */
  async transpile(context, id, code, options = {}) {
    const source = this.getSourceFile(id, code);
    return this.transpileModule(context, source, options);
  }
  /**
  * Compile the source code.
  *
  * @param context - The compiler context.
  * @param id - The name of the file to compile.
  * @param code - The source code to compile.
  * @returns The compiled source code and source map.
  */
  async compile(context, id, code, options = {}) {
    this.log(types.LogLevelLabel.TRACE, `Compiling ${id}`);
    const source = this.getSourceFile(id, code);
    let transpiled;
    if (!options.skipCache) {
      transpiled = await this.getCache(context, source);
      if (transpiled) {
        this.log(types.LogLevelLabel.TRACE, `Cache hit: ${source.id}`);
      } else {
        this.log(types.LogLevelLabel.TRACE, `Cache miss: ${source.id}`);
      }
    }
    if (!transpiled) {
      transpiled = await this.transpileModule(context, source, options);
      await this.setCache(context, source, transpiled);
    }
    return transpiled;
  }
  /**
  * Get the source file.
  *
  * @param id - The name of the file.
  * @param code - The source code.
  * @returns The source file.
  */
  getSourceFile(id, code) {
    const content = code ?? readFile.readFileIfExistingSync(id);
    return {
      id,
      code: chunkXSCSXEQC_cjs.getMagicString(content),
      env: []
    };
  }
  /**
  * Get the result of the compiler.
  *
  * @param sourceFile - The source file.
  * @param transpiled - The transpiled source code.
  * @returns The result of the compiler.
  */
  getResult(sourceFile, transpiled) {
    return chunkB3D7OHHL_cjs.generateSourceMap(sourceFile.id, sourceFile.code, transpiled);
  }
  async getCache(context, sourceFile) {
    let cache = this.#cache.get(sourceFile);
    if (cache) {
      return cache;
    }
    if (context.options.skipCache) {
      return;
    }
    cache = await chunkNAJ36BYA_cjs.getCache(sourceFile, this.cacheDir);
    if (cache) {
      this.#cache.set(sourceFile, cache);
    }
    return cache;
  }
  async setCache(context, sourceFile, transpiled) {
    if (transpiled) {
      this.#cache.set(sourceFile, transpiled);
    } else {
      this.#cache.delete(sourceFile);
    }
    if (context.options.skipCache) {
      return;
    }
    return chunkNAJ36BYA_cjs.setCache(sourceFile, this.cacheDir, transpiled);
  }
  /**
  * Transpile the module.
  *
  * @param context - The compiler context.
  * @param source - The compiler source file.
  * @param options - The transpile options.
  * @returns The transpiled module.
  */
  async transpileModule(context, source, options = {}) {
    this.log(types.LogLevelLabel.TRACE, `Transpiling ${source.id} module with TypeScript compiler`);
    let transformed = source;
    if (options.onPreTransform) {
      await Promise.resolve(options.onPreTransform(context, source));
    }
    if (this.#options.onPreTransform) {
      await Promise.resolve(this.#options.onPreTransform(context, source));
    }
    if (!options.skipTransform) {
      if (context.options.platform === "node") {
        chunk4MM4BJX6_cjs.transformContext(source);
      }
      if (!options.skipEnvTransform) {
        transformed = await chunkYRPB2JS5_cjs.transformEnv(this.log, source, context);
      }
      if (!options.skipErrorsTransform) {
        await chunkZW7CBT5E_cjs.transformErrors(this.log, transformed, context);
      }
      if (this.#options.onTransform) {
        await Promise.resolve(this.#options.onTransform(context, transformed));
      }
    }
    if (context.unimport && !transformed.id.replaceAll("\\", "/").includes(joinPaths.joinPaths(context.artifactsDir, "runtime"))) {
      transformed = await context.unimport.injectImports(transformed);
    }
    if (this.#options.onPostTransform) {
      await Promise.resolve(this.#options.onPostTransform(context, transformed));
    }
    if (options.onPostTransform) {
      await Promise.resolve(options.onPostTransform(context, transformed));
    }
    const transpiled = ts__default.default.transpileModule(transformed.code.toString(), {
      compilerOptions: {
        ...context.tsconfig.options,
        configFilePath: context.options.tsconfig
      },
      fileName: transformed.id,
      transformers: {
        before: [
          typeCompiler.transformer
        ],
        after: [
          typeCompiler.declarationTransformer
        ]
      }
    });
    if (transpiled === null) {
      this.log(types.LogLevelLabel.ERROR, `Transform is null: ${transformed.id}`);
      throw new Error(`Transform is null: ${transformed.id}`);
    } else {
      this.log(types.LogLevelLabel.TRACE, `Transformed: ${transformed.id}`);
    }
    return transpiled.outputText;
  }
};

exports.Compiler = Compiler;
//# sourceMappingURL=chunk-BNXCMVRQ.cjs.map
//# sourceMappingURL=chunk-BNXCMVRQ.cjs.map