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:
@@ -0,0 +1,72 @@
|
||||
import type { Rule } from 'eslint';
|
||||
import path from 'node:path';
|
||||
|
||||
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 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 from outside facade directory in facade files',
|
||||
},
|
||||
messages: {
|
||||
noExternalImports: 'Facade files are published as a separate package entry. Do not import package-internal runtime modules through "{{importPath}}"; it can duplicate module singletons when consumers import both the package root and the facade entry. Move the needed symbol to the package root export if necessary, then import it through the package name. Type-only imports should also use a public package entry.',
|
||||
},
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const filename = getRuleFilename(context);
|
||||
const normalizedPath = filename.split(path.sep).join('/');
|
||||
const isFacadeFile = normalizedPath.includes('/facade/');
|
||||
|
||||
if (!isFacadeFile) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const currentDir = path.dirname(filename);
|
||||
|
||||
return {
|
||||
ImportDeclaration(node: Rule.Node) {
|
||||
const importPath = getImportSourceValue(node);
|
||||
|
||||
if (!importPath || !importPath.startsWith('.')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resolvedPath = path.resolve(currentDir, importPath).split(path.sep).join('/');
|
||||
|
||||
if (!resolvedPath.includes('/facade/')) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'noExternalImports',
|
||||
data: { importPath },
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
export default rule;
|
||||
Reference in New Issue
Block a user