Skip to content

Commit

Permalink
Allow type imports only in webview preloads (#204639)
Browse files Browse the repository at this point in the history
  • Loading branch information
rebornix authored Feb 7, 2024
1 parent cc2934a commit cfa5001
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 0 deletions.
66 changes: 66 additions & 0 deletions .eslintplugin/code-no-runtime-import.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { TSESTree } from '@typescript-eslint/typescript-estree';
import * as eslint from 'eslint';
import { dirname, join, relative } from 'path';
import minimatch from 'minimatch';
import { createImportRuleListener } from './utils';

export = new class implements eslint.Rule.RuleModule {

readonly meta: eslint.Rule.RuleMetaData = {
messages: {
layerbreaker: 'You are only allowed to import {{import}} from here using `import type ...`.'
},
schema: {
type: "array",
items: {
type: "object",
additionalProperties: {
type: "array",
items: {
type: "string"
}
}
}
}
};

create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener {
let fileRelativePath = relative(dirname(__dirname), context.getFilename());
if (!fileRelativePath.endsWith('/')) {
fileRelativePath += '/';
}
const ruleArgs = <Record<string, string[]>>context.options[0];

const matchingKey = Object.keys(ruleArgs).find(key => fileRelativePath.startsWith(key) || minimatch(fileRelativePath, key));
if (!matchingKey) {
// nothing
return {};
}

const restrictedImports = ruleArgs[matchingKey];
return createImportRuleListener((node, path) => {
if (path[0] === '.') {
path = join(dirname(context.getFilename()), path);
}

if ((
restrictedImports.includes(path) || restrictedImports.some(restriction => minimatch(path, restriction))
) && !(
(node.parent?.type === TSESTree.AST_NODE_TYPES.ImportDeclaration && node.parent.importKind === 'type') ||
(node.parent && 'exportKind' in node.parent && node.parent.exportKind === 'type'))) { // the export could be multiple types
context.report({
loc: node.parent!.loc,
messageId: 'layerbreaker',
data: {
import: path
}
});
}
});
}
};
13 changes: 13 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,19 @@
}
]
}
},
{
"files": [
"src/vs/workbench/contrib/notebook/browser/view/renderers/*.ts"
],
"rules": {
"local/code-no-runtime-import": [
"error",
{
"src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts": ["**/*"]
}
]
}
}
]
}

2 comments on commit cfa5001

@shagahmed
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copyright (c) Microsoft Corporation. All rights reserved.

  • Licensed under the MIT License. See License.txt in the project root for license information.

@shagahmed
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copyright (c) Microsoft Corporation. All rights reserved.

  • Licensed under the MIT License. See License.txt in the project root for license information.

Please sign in to comment.