UNPKG

@adonisjs/require-ts

Version:
196 lines (195 loc) 6.15 kB
"use strict"; /* * @adonisjs/require-ts * * (c) Harminder Virk <virk@adonisjs.comharminder@cav.ai> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.Config = void 0; const path_1 = require("path"); const fs_extra_1 = require("fs-extra"); const utils_1 = require("../utils"); const Cache_1 = require("../Cache"); const DiagnosticsReporter_1 = require("../DiagnosticsReporter"); /** * Exposes the API to parse tsconfig file and cache it until the * contents of the file are changed. */ class Config { constructor(appRoot, cacheRoot, ts, usesCache = true) { this.appRoot = appRoot; this.cacheRoot = cacheRoot; this.ts = ts; this.usesCache = usesCache; /** * Hard assumption has been made that config file name * is "tsconfig.json" */ this.configFilePath = (0, path_1.join)(this.appRoot, 'tsconfig.json'); /** * Reference to the cache */ this.cache = this.usesCache ? new Cache_1.Cache(this.appRoot, this.cacheRoot) : new Cache_1.FakeCache(); /** * Dignostic reporter to print program errors */ this.diagnosticsReporter = this.ts ? new DiagnosticsReporter_1.DiagnosticsReporter(this.appRoot, this.ts, false) : undefined; } /** * Returns the raw contents of the config file. We need to read this * always to generate the hash and then look for the cached config * file. */ getConfigRawContents() { (0, utils_1.debug)('checking for tsconfig "%s"', this.configFilePath); try { return (0, fs_extra_1.readFileSync)(this.configFilePath, 'utf-8'); } catch (error) { if (error.code === 'ENOENT') { throw new Error('"@adonisjs/require-ts" expects the "tsconfig.json" file to exists in the app root'); } throw error; } } /** * Parses the ts config using the typescript compiler */ parseTsConfig() { let exception = null; (0, utils_1.debug)('parse tsconfig file'); if (!this.ts) { throw new Error('Cannot parse typescript config. Make sure to instantiate Config class with typescript compiler'); } /** * Parse config using typescript compiler */ const config = this.ts.getParsedCommandLineOfConfigFile(this.configFilePath, {}, { ...this.ts.sys, useCaseSensitiveFileNames: true, getCurrentDirectory: () => this.appRoot, onUnRecoverableConfigFileDiagnostic: (error) => (exception = error), }); /** * Return exception as it is */ if (exception) { return { error: exception, options: null, }; } /** * Return diagnostic errors if any */ if (config.errors && config.errors.length) { return { error: config.errors, options: null, }; } /** * Return compiler options */ return { error: null, options: config.options, }; } /** * Parses the cached config string as JSON. Errors * are ignored and hence cache is ignored too */ parseConfigAsJson(config) { if (!config) { return null; } try { return JSON.parse(config); } catch (error) { return null; } } /** * Extracts transformers the tsconfig file contents */ extractTransformers(rawConfig) { try { const transformers = JSON.parse(rawConfig).transformers || {}; return { before: transformers.before, after: transformers.after, afterDeclarations: transformers.afterDeclarations, }; } catch (error) { } } /** * Returns the config file from the cache or returns null when there is * no cache */ getCached() { const rawContents = this.getConfigRawContents(); const cachePath = this.cache.makeCachePath(this.configFilePath, rawContents, '.json'); return { raw: rawContents, cachePath, cached: this.parseConfigAsJson(this.cache.get(cachePath)), }; } /** * Parses config and returns the compiler options */ parse() { if (!this.diagnosticsReporter) { throw new Error('Cannot parse typescript config. Make sure to instantiate Config class with typescript compiler'); } /** * Cache exists and is upto date */ const { cached, raw, cachePath } = this.getCached(); if (cached && cached.version === Config.version) { return { version: cached.version, error: null, options: { compilerOptions: cached.options.compilerOptions, transformers: cached.options.transformers, }, }; } /** * Parse the config using the compiler */ const config = this.parseTsConfig(); if (config.error) { this.diagnosticsReporter.report(config.error); return { version: Config.version, options: null, error: config.error, }; } /** * Write to cache to avoid future parsing */ const parsed = { version: Config.version, error: null, options: { compilerOptions: config.options, transformers: this.extractTransformers(raw), }, }; this.cache.set(cachePath, JSON.stringify(parsed)); return parsed; } } exports.Config = Config; Config.version = 'v1';