@nxext/stencil
Version:
Nx plugin for stenciljs
148 lines • 7.02 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createStencilEslintJson = exports.augmentStencilEslintFlatConfig = exports.beginningOfEsLintConfigJs = exports.beginningOfEsLintConfigJsEsm = exports.beginningOfEsLintConfigJsCjs = exports.extraEslintDependencies = void 0;
exports.getEsLintPluginBaseName = getEsLintPluginBaseName;
const versions_1 = require("./versions");
const devkit_1 = require("@nx/devkit");
const tsquery_1 = require("@phenomnomnominal/tsquery");
const typescript_1 = require("typescript");
const js_1 = require("@nx/js");
const node_os_1 = require("node:os");
const node_path_1 = require("node:path");
const common_1 = require("@nxext/common");
exports.extraEslintDependencies = {
dependencies: {},
devDependencies: {
[versions_1.eslintImportPlugin]: versions_1.ESLINT_PLUGIN_VERSIONS[versions_1.eslintImportPlugin],
[versions_1.stencilEslintPlugin]: versions_1.ESLINT_PLUGIN_VERSIONS[versions_1.stencilEslintPlugin],
},
};
function getEsLintPluginBaseName(packageName) {
if (packageName.startsWith('eslint-plugin-')) {
return packageName.replace('eslint-plugin-', '');
}
else if (packageName.endsWith('/eslint-plugin')) {
return packageName.replace('/eslint-plugin', '');
}
throw Error(`[stencil] unsupported eslint plugin name: ${packageName}`);
}
exports.beginningOfEsLintConfigJsCjs = `const importPlugin = require('eslint-plugin-import');
/**
* @stencil-community/eslint-plugin may not support the flat config yet
*
* TODO: activate @stencil-community/eslint-plugin when it supports the flat config
*
* const stencilPlugin = require('@stencil-community/eslint-plugin');
*/
`;
exports.beginningOfEsLintConfigJsEsm = `import importPlugin from 'eslint-plugin-import';
/**
* @stencil-community/eslint-plugin may not support the flat config yet
*
* TODO: activate @stencil-community/eslint-plugin when it supports the flat config
*
* import stencilPlugin from '@stencil-community/eslint-plugin';
*/
`;
// Kept for backwards compatibility with existing imports/tests; the CJS form
// only fits a module.exports-shaped config (see augmentStencilEslintFlatConfig).
exports.beginningOfEsLintConfigJs = exports.beginningOfEsLintConfigJsCjs;
const augmentStencilEslintFlatConfig = (tree, eslintFlatConfigFileContent, eslintFlatConfigFilePath) => {
var _a;
let sourceFile = tsquery_1.tsquery.ast(eslintFlatConfigFileContent, eslintFlatConfigFilePath, typescript_1.ScriptKind.JS);
const [configArrayNodeBeforeInsert] = tsquery_1.tsquery
.query(sourceFile, 'ArrayLiteralExpression')
.filter((configArrayNode) => {
var _a, _b;
const ejsExport = ((_a = configArrayNode.parent) === null || _a === void 0 ? void 0 : _a.kind) === typescript_1.SyntaxKind.ExportAssignment;
const cjsExport = ((_b = configArrayNode.parent) === null || _b === void 0 ? void 0 : _b.kind) === typescript_1.SyntaxKind.BinaryExpression &&
(configArrayNode.parent.getText().startsWith('module.exports =') ||
configArrayNode.parent.getText().startsWith('exports ='));
return ejsExport || cjsExport;
});
// `eslint.config.mjs` (Nx's current default) is a real ES module — a CJS
// `require()` there throws at load time. Emit the matching import form
// instead of always assuming CommonJS.
const isEsm = ((_a = configArrayNodeBeforeInsert === null || configArrayNodeBeforeInsert === void 0 ? void 0 : configArrayNodeBeforeInsert.parent) === null || _a === void 0 ? void 0 : _a.kind) === typescript_1.SyntaxKind.ExportAssignment;
sourceFile = (0, js_1.insertChange)(tree, sourceFile, eslintFlatConfigFilePath, 0, isEsm ? exports.beginningOfEsLintConfigJsEsm : exports.beginningOfEsLintConfigJsCjs);
const [configArrayNode] = tsquery_1.tsquery
.query(sourceFile, 'ArrayLiteralExpression')
.filter((configArrayNode) => {
var _a, _b;
const ejsExport = ((_a = configArrayNode.parent) === null || _a === void 0 ? void 0 : _a.kind) === typescript_1.SyntaxKind.ExportAssignment;
const cjsExport = ((_b = configArrayNode.parent) === null || _b === void 0 ? void 0 : _b.kind) === typescript_1.SyntaxKind.BinaryExpression &&
(configArrayNode.parent.getText().startsWith('module.exports =') ||
configArrayNode.parent.getText().startsWith('exports ='));
return ejsExport || cjsExport;
});
if (configArrayNode) {
(0, js_1.replaceChange)(tree, sourceFile, eslintFlatConfigFilePath, configArrayNode.getFullStart(), `[
/**
* TODO: activate @stencil-community/eslint-plugin when it supports the flat config
*
* stencilPlugin.flatConfigs.recommended
*/
importPlugin.flatConfigs.recommended,
importPlugin.flatConfigs.typescript,
${configArrayNode.elements
.map((node) => node.getFullText())
.join(`,${node_os_1.EOL} `)},
{
ignores: ['!**/*'],
},
{
files: ['*.ts', '*.tsx'],
rules: {},
},
{
files: ['**/*.ts', '**/*.tsx'],
rules: {
/**
* Stencil's own generated \`src/index.ts\` re-exports \`./components\`,
* resolved only via the sibling \`components.d.ts\` ambient declaration
* (a type-only file, valid to tsc) — eslint-plugin-import's default
* resolver doesn't follow that convention without extra TypeScript
* resolver config, so it flags a false positive here.
*/
'import/no-unresolved': 'off',
},
},
{
files: ['*.js', '*.jsx'],
rules: {},
},
]`, configArrayNode.getFullText());
}
return () => {
devkit_1.logger.warn(`@stencil-community/eslint-plugin may not support the flat config yet.`);
devkit_1.logger.warn(`update this file:`);
devkit_1.logger.warn((0, common_1.getTerminalLinkForAbsolutePath)((0, node_path_1.join)(devkit_1.workspaceRoot, eslintFlatConfigFilePath)));
devkit_1.logger.warn(`once the plugin does support the flat config.`);
};
};
exports.augmentStencilEslintFlatConfig = augmentStencilEslintFlatConfig;
const createStencilEslintJson = (projectRoot) => ({
extends: [
`plugin:${getEsLintPluginBaseName(versions_1.stencilEslintPlugin)}/recommended`,
`plugin:${getEsLintPluginBaseName(versions_1.eslintImportPlugin)}/recommended`,
`plugin:${getEsLintPluginBaseName(versions_1.eslintImportPlugin)}/typescript`,
`${(0, devkit_1.offsetFromRoot)(projectRoot)}.eslintrc.json`,
],
ignorePatterns: ['!**/*'],
overrides: [
{
files: ['*.ts', '*.tsx'],
/**
* Having an empty rules object present makes it more obvious to the user where they would
* extend things from if they needed to
*/
rules: {},
},
{
files: ['*.js', '*.jsx'],
rules: {},
},
],
});
exports.createStencilEslintJson = createStencilEslintJson;
//# sourceMappingURL=lint.js.map