diff --git a/src/Umbraco.Web.UI.Client/.eslintrc.json b/src/Umbraco.Web.UI.Client/.eslintrc.json index 32cc406cec..55525707e8 100644 --- a/src/Umbraco.Web.UI.Client/.eslintrc.json +++ b/src/Umbraco.Web.UI.Client/.eslintrc.json @@ -2,7 +2,7 @@ "ignorePatterns": ["vite.*.ts"], "root": true, "extends": ["eslint:recommended", "plugin:import/recommended", "prettier"], - "plugins": ["import"], + "plugins": ["import", "eslint-plugin-local-rules"], "overrides": [ { "files": ["**/*.ts"], @@ -31,7 +31,8 @@ }, "rules": { "no-var": "error", - "import/no-unresolved": "error" + "import/no-unresolved": "error", + "local-rules/bad-type-import": "error" }, "settings": { "import/parsers": { diff --git a/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs b/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs new file mode 100644 index 0000000000..b124352065 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs @@ -0,0 +1,36 @@ +'use strict'; + +/* + * A eslint rule that ensures the use of the `import type` operator from the `src/core/models/index.ts` file. + */ +// eslint-disable-next-line no-undef +/** @type {import('eslint').Rule.RuleModule} */ +module.exports = { + 'bad-type-import': { + meta: { + type: 'problem', + docs: { + description: 'Ensures the use of the `import type` operator from the `src/core/models/index.ts` file.', + category: 'Best Practices', + recommended: true, + }, + fixable: 'code', + schema: [], + }, + create: function (context) { + return { + ImportDeclaration: function (node) { + if (node.source.parent.importKind !== 'type' && (node.source.value.endsWith('core/models') || node.source.value === 'router-slot/model')) { + const sourceCode = context.getSourceCode(); + const nodeSource = sourceCode.getText(node); + context.report({ + node, + message: 'Use `import type` instead of `import`.', + fix: fixer => fixer.replaceText(node, nodeSource.replace('import', 'import type')), + }); + } + }, + }; + } + } +}; diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 4faa01f6d5..b3af37461e 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -49,6 +49,7 @@ "eslint-plugin-import": "^2.26.0", "eslint-plugin-lit": "^1.6.1", "eslint-plugin-lit-a11y": "^2.2.2", + "eslint-plugin-local-rules": "^1.3.1", "eslint-plugin-storybook": "^0.6.4", "lit-html": "^2.3.1", "msw": "^0.45.0", @@ -12288,6 +12289,12 @@ "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", "dev": true }, + "node_modules/eslint-plugin-local-rules": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-local-rules/-/eslint-plugin-local-rules-1.3.1.tgz", + "integrity": "sha512-ezuHRUXzRwFY3jFaX9vz8vxLLdLLIrbXBnVM6rip71/zjnIBaExY2vsm316temX+P3tasjQ2ciadWOTnnOUCgA==", + "dev": true + }, "node_modules/eslint-plugin-storybook": { "version": "0.6.4", "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-0.6.4.tgz", @@ -35952,6 +35959,12 @@ } } }, + "eslint-plugin-local-rules": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-local-rules/-/eslint-plugin-local-rules-1.3.1.tgz", + "integrity": "sha512-ezuHRUXzRwFY3jFaX9vz8vxLLdLLIrbXBnVM6rip71/zjnIBaExY2vsm316temX+P3tasjQ2ciadWOTnnOUCgA==", + "dev": true + }, "eslint-plugin-storybook": { "version": "0.6.4", "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-0.6.4.tgz", diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 271937fec6..37ad82bc6a 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -38,16 +38,16 @@ "dependencies": { "@umbraco-ui/uui": "^1.0.0", "@umbraco-ui/uui-css": "^1.0.0", + "@umbraco-ui/uui-modal": "file:umbraco-ui-uui-modal-0.0.0.tgz", + "@umbraco-ui/uui-modal-container": "file:umbraco-ui-uui-modal-container-0.0.0.tgz", + "@umbraco-ui/uui-modal-dialog": "file:umbraco-ui-uui-modal-dialog-0.0.0.tgz", + "@umbraco-ui/uui-modal-sidebar": "file:umbraco-ui-uui-modal-sidebar-0.0.0.tgz", "element-internals-polyfill": "^1.1.9", "lit": "^2.3.1", "openapi-typescript-fetch": "^1.1.3", "router-slot": "^1.5.5", "rxjs": "^7.5.6", - "uuid": "^8.3.2", - "@umbraco-ui/uui-modal": "file:umbraco-ui-uui-modal-0.0.0.tgz", - "@umbraco-ui/uui-modal-container": "file:umbraco-ui-uui-modal-container-0.0.0.tgz", - "@umbraco-ui/uui-modal-dialog": "file:umbraco-ui-uui-modal-dialog-0.0.0.tgz", - "@umbraco-ui/uui-modal-sidebar": "file:umbraco-ui-uui-modal-sidebar-0.0.0.tgz" + "uuid": "^8.3.2" }, "devDependencies": { "@babel/core": "^7.18.13", @@ -76,6 +76,7 @@ "eslint-plugin-import": "^2.26.0", "eslint-plugin-lit": "^1.6.1", "eslint-plugin-lit-a11y": "^2.2.2", + "eslint-plugin-local-rules": "^1.3.1", "eslint-plugin-storybook": "^0.6.4", "lit-html": "^2.3.1", "msw": "^0.45.0",