ts-lit-plugin
Version:
Typescript plugin that adds type checking and code completion to lit-html
135 lines (134 loc) • 6.26 kB
JavaScript
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
/* eslint-disable @typescript-eslint/no-explicit-any */
var lit_analyzer_1 = require("lit-analyzer");
var ts = __importStar(require("typescript"));
var web_component_analyzer_1 = require("web-component-analyzer");
var decorate_language_service_1 = require("./decorate-language-service");
var logger_1 = require("./logger");
var lit_plugin_context_1 = require("./ts-lit-plugin/lit-plugin-context");
var ts_lit_plugin_1 = require("./ts-lit-plugin/ts-lit-plugin");
var ts_module_1 = require("./ts-module");
var tsHtmlPluginSymbol = Symbol.for("__tsHtmlPlugin__");
var context = undefined;
/**
* Export a function for the ts-service to initialize our plugin.
* @param typescript
*/
function init(_a) {
var typescript = _a.typescript;
// Cache the typescript module
ts_module_1.setTypescriptModule(typescript);
/**
* This function is used to print debug info once
* Yes, it's a self destructing function!
*/
var printDebugOnce = function () {
if (logger_1.logger.level >= lit_analyzer_1.LitAnalyzerLoggerLevel.DEBUG) {
logger_1.logger.debug("Lit Analyzer: " + lit_analyzer_1.VERSION);
logger_1.logger.debug("Web Component Analyzer: " + web_component_analyzer_1.VERSION);
logger_1.logger.debug("Installed Typescript: " + ts.version);
logger_1.logger.debug("Running Typescript: " + typescript.version);
logger_1.logger.debug("DIRNAME: " + __dirname);
printDebugOnce = undefined;
}
};
return {
create: function (info) {
// Check if the language service is already decorated
if (info.languageService[tsHtmlPluginSymbol] != null) {
return info.languageService;
}
// Save the current working directory
info.config.cwd = info.config.cwd || info.project.getCurrentDirectory();
// Extend existing language service with the plugin functions
try {
context = new lit_plugin_context_1.LitPluginContext({
ts: typescript,
getProgram: function () {
return info.languageService.getProgram();
},
getProject: function () {
return info.project;
}
});
context.updateConfig(lit_analyzer_1.makeConfig(info.config));
logger_1.logger.verbose("Starting ts-lit-plugin...");
if (printDebugOnce != null)
printDebugOnce();
var plugin = new ts_lit_plugin_1.TsLitPlugin(info.languageService, context);
var decoratedService = decorate_language_service_1.decorateLanguageService(info.languageService, plugin);
// Save that we've extended this service to prevent extending it again
decoratedService[tsHtmlPluginSymbol] = plugin;
return decoratedService;
}
catch (e) {
logger_1.logger.error("ts-lit-plugin crashed while decorating the language service...", e);
return info.languageService;
}
},
/**
* Unfortunately this function isn't called with configuration from tsconfig.json
* @param externalConfig
*/
onConfigurationChanged: function (externalConfig) {
var _a;
if (context == null || externalConfig == null)
return;
// Manually merge in configuration from "tsconfig.json"
var compilerOptions = (_a = context.project) === null || _a === void 0 ? void 0 : _a.getCompilerOptions();
var tsLitPluginOptions = compilerOptions != null ? readLitAnalyzerConfigFromCompilerOptions(compilerOptions) : undefined;
// Make seed where options from "external" takes precedence over options from "tsconfig.json"
var configSeed = __assign(__assign(__assign({}, (tsLitPluginOptions || {})), externalConfig), {
// Also merge rules deep
rules: __assign(__assign({}, ((tsLitPluginOptions === null || tsLitPluginOptions === void 0 ? void 0 : tsLitPluginOptions.rules) || {})), (externalConfig.rules || {})) });
context.updateConfig(lit_analyzer_1.makeConfig(configSeed));
if (printDebugOnce != null)
printDebugOnce();
}
};
}
/**
* Resolves the nearest tsconfig.json and returns the configuration seed within the plugins section for "ts-lit-plugin"
*/
function readLitAnalyzerConfigFromCompilerOptions(compilerOptions) {
// Finds the plugin section
if ("plugins" in compilerOptions) {
var plugins = compilerOptions.plugins;
var tsLitPluginOptions = plugins.find(function (plugin) { return plugin.name === "ts-lit-plugin"; });
if (tsLitPluginOptions != null) {
return tsLitPluginOptions;
}
}
return undefined;
}
module.exports = init;