snapshot of https://github.com/dream-num/univer.git (dev, 2026-09-16; blobs > 131072B omitted)
Some checks failed
📦 Build / build (push) Has been cancelled
🧪 CI Test / test shard (1/4) (push) Has been cancelled
🧪 CI Test / test shard (2/4) (push) Has been cancelled
🧪 CI Test / test shard (3/4) (push) Has been cancelled
🧪 CI Test / test shard (4/4) (push) Has been cancelled
🧪 CI Test / test (push) Has been cancelled
🧪 CI Test / eslint (push) Has been cancelled
🧪 CI Test / typecheck (push) Has been cancelled
🔫 Sync to Pro / dispatch-sync (push) Has been cancelled
🔮 Sync Mirror / sync (push) Has been cancelled
Some checks failed
📦 Build / build (push) Has been cancelled
🧪 CI Test / test shard (1/4) (push) Has been cancelled
🧪 CI Test / test shard (2/4) (push) Has been cancelled
🧪 CI Test / test shard (3/4) (push) Has been cancelled
🧪 CI Test / test shard (4/4) (push) Has been cancelled
🧪 CI Test / test (push) Has been cancelled
🧪 CI Test / eslint (push) Has been cancelled
🧪 CI Test / typecheck (push) Has been cancelled
🔫 Sync to Pro / dispatch-sync (push) Has been cancelled
🔮 Sync Mirror / sync (push) Has been cancelled
This commit is contained in:
137
common/shared/eslint/plugins/no-facade-imports-outside-facade.ts
Normal file
137
common/shared/eslint/plugins/no-facade-imports-outside-facade.ts
Normal file
@@ -0,0 +1,137 @@
|
||||
import type { Rule } from 'eslint';
|
||||
import path from 'node:path';
|
||||
|
||||
interface IRuleOptions { ignore?: unknown[] }
|
||||
|
||||
function getImportSourceValue(node: Rule.Node): string | null {
|
||||
if (!('source' in node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const source = (node as { source?: { value?: unknown } }).source;
|
||||
if (!source || typeof source.value !== 'string') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return source.value;
|
||||
}
|
||||
|
||||
function normalizePath(filePath: string): string {
|
||||
return filePath.split(path.sep).join('/');
|
||||
}
|
||||
|
||||
function shouldIgnoreFile(normalizedFilePath: string, ignorePaths: readonly unknown[]): boolean {
|
||||
return ignorePaths.some((ignorePath: unknown) => {
|
||||
if (typeof ignorePath !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const normalizedIgnorePath = normalizePath(ignorePath).replace(/^\.\//, '');
|
||||
|
||||
if (!normalizedIgnorePath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return normalizedFilePath === normalizedIgnorePath
|
||||
|| normalizedFilePath.endsWith(`/${normalizedIgnorePath}`)
|
||||
|| normalizedFilePath.includes(normalizedIgnorePath);
|
||||
});
|
||||
}
|
||||
|
||||
function getRuleFilename(context: Rule.RuleContext): string {
|
||||
const filenameFromProperty = (context as { filename?: unknown }).filename;
|
||||
|
||||
if (typeof filenameFromProperty === 'string' && filenameFromProperty) {
|
||||
return filenameFromProperty;
|
||||
}
|
||||
|
||||
const getFilename = (context as { getFilename?: () => string }).getFilename;
|
||||
return typeof getFilename === 'function' ? getFilename.call(context) : '';
|
||||
}
|
||||
|
||||
const rule: Rule.RuleModule = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Disallow imports containing facade in non-facade files',
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
ignore: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
messages: {
|
||||
noFacadeImports: 'Imports containing "facade" are not allowed in non-facade files: "{{importPath}}"',
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const filename = getRuleFilename(context);
|
||||
const normalizedPath = normalizePath(filename);
|
||||
const [ruleOptions = {} as IRuleOptions] = context.options as [IRuleOptions?];
|
||||
const ignorePaths = Array.isArray(ruleOptions.ignore) ? ruleOptions.ignore : [];
|
||||
|
||||
if (shouldIgnoreFile(normalizedPath, ignorePaths)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const isInPackages = normalizedPath.includes('/packages/');
|
||||
const isInFacade = normalizedPath.includes('/facade/');
|
||||
|
||||
if (!isInPackages || isInFacade) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// get parent dir
|
||||
const parentDirMatch = normalizedPath.match(/\/([^/]+)\/packages\//);
|
||||
if (!parentDirMatch) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
ImportDeclaration(node: Rule.Node) {
|
||||
const importPath = getImportSourceValue(node);
|
||||
|
||||
// Check if the import path contains 'facade'
|
||||
if (importPath?.includes('facade')) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'noFacadeImports',
|
||||
data: { importPath },
|
||||
});
|
||||
}
|
||||
},
|
||||
ExportNamedDeclaration(node: Rule.Node) {
|
||||
const exportPath = getImportSourceValue(node);
|
||||
if (exportPath?.includes('facade')) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'noFacadeImports',
|
||||
data: { importPath: exportPath },
|
||||
});
|
||||
}
|
||||
},
|
||||
ExportAllDeclaration(node: Rule.Node) {
|
||||
const exportPath = getImportSourceValue(node);
|
||||
if (exportPath?.includes('facade')) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'noFacadeImports',
|
||||
data: { importPath: exportPath },
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
export default rule;
|
||||
Reference in New Issue
Block a user