UNPKG

@nextcloud/eslint-config

Version:

Eslint shared config for nextcloud apps and libraries

98 lines (97 loc) 4.6 kB
/*! * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ import { createLibVersionValidator } from "../utils/lib-version-parser.js"; /* Introduced in @nextcloud/vue v8.23.0 https://github.com/nextcloud-libraries/nextcloud-vue/pull/6385 */ const rule = { meta: { docs: { description: 'Deprecated @nextcloud/vue import syntax', recommended: true, }, fixable: 'code', messages: { outdatedVueLibrary: 'Installed @nextcloud/vue library is outdated and does not support all reported errors. Install latest compatible version', deprecatedDist: 'Import from "@nextcloud/vue/dist" is deprecated', deprecatedMixin: 'Mixins are no longer recommended by Vue. Consider using available alternatives', deprecatedNcSettingsInputText: 'NcSettingsInputText is deprecated. Consider using available alternatives', deprecatedTooltip: 'Tooltip directive is deprecated. use native title attribute or NcPopover instead', }, }, create(context) { const versionSatisfies = createLibVersionValidator(context); const isVersionValidForDist = versionSatisfies('8.23.0'); const oldPattern = '@nextcloud/vue/dist/([^/]+)/([^/.]+)'; // Matches both the legacy `dist/Mixins/*` path and a bare `mixins/*` path. // There is no clean `@nextcloud/vue/mixins/*` subpath export (only components, // composables, directives and functions), so mixins must be migrated to // composables rather than have their import path rewritten. const mixinPattern = '@nextcloud/vue/(?:dist/)?mixins/([^/.]+)'; const isVersionValidForTooltip = versionSatisfies('8.25.0'); const tooltipPattern = '@nextcloud/vue/directives/Tooltip'; const isVersionValidForNcSettingsInputText = versionSatisfies('8.31.0'); const patternForNcSettingsInputText = '@nextcloud/vue/components/NcSettingsInputText'; return { ImportDeclaration: function (node) { const importPath = node.source.value; const matchForNcSettingsInputText = importPath.match(new RegExp(patternForNcSettingsInputText)); if (matchForNcSettingsInputText) { if (!isVersionValidForNcSettingsInputText) { context.report({ node, messageId: 'outdatedVueLibrary' }); return; } context.report({ node, messageId: 'deprecatedNcSettingsInputText', }); } const mixinMatch = importPath.match(new RegExp(mixinPattern, 'i')); if (mixinMatch) { if (!isVersionValidForDist) { context.report({ node, messageId: 'outdatedVueLibrary' }); return; } context.report({ node, messageId: 'deprecatedMixin', }); } const tooltipMatch = importPath.match(new RegExp(tooltipPattern)); if (tooltipMatch) { if (!isVersionValidForTooltip) { context.report({ node, messageId: 'outdatedVueLibrary' }); return; } context.report({ node, messageId: 'deprecatedTooltip', }); } const match = importPath.match(new RegExp(oldPattern)); if (match) { if (!isVersionValidForDist) { context.report({ node, messageId: 'outdatedVueLibrary' }); return; } // Mixins removed in v9 and already reported as `deprecatedMixin` if (match[1].toLowerCase() === 'mixins') { return; } const newImportPath = `'@nextcloud/vue/${match[1].toLowerCase()}/${match[2]}'`; context.report({ node, messageId: 'deprecatedDist', fix(fixer) { return fixer.replaceText(node.source, newImportPath); }, }); } }, }; }, }; export default rule;