@nextcloud/eslint-config 9.0.0-rc.7 → 9.0.0-rc.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -69,6 +69,8 @@ Please refer to the README on how to adjust your configuration for flat config.
69
69
  * fix(nextcloud): add missing deprecations and removals [\#1206](https://github.com/nextcloud-libraries/eslint-config/pull/1206) \([susnux](https://github.com/susnux)\)
70
70
  * fix(plugin:nextcloud-vue): use resolved dependency for detecting nextcloud-vue version [\#1220](https://github.com/nextcloud-libraries/eslint-config/pull/1220) \([susnux](https://github.com/susnux)\)
71
71
  * fix: switch to `@stylistic/exp-list-style` to resolve array edge-cases [\#1203](https://github.com/nextcloud-libraries/eslint-config/pull/1203) \([susnux](https://github.com/susnux)\)
72
+ * fix(nextcloud-plugin): add more removed API in Nextcloud 33 [\#1269](https://github.com/nextcloud-libraries/eslint-config/pull/1269) \([susnux](https://github.com/susnux)\)
73
+ * fix: use vue-eslint-parser directly [\#1277](https://github.com/nextcloud-libraries/eslint-config/pull/1277) \([susnux](https://github.com/susnux)\)
72
74
 
73
75
  ### Changed
74
76
  * Add SPDX header [#802](https://github.com/nextcloud-libraries/eslint-config/pull/802)
@@ -2,12 +2,12 @@
2
2
  * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
3
3
  * SPDX-License-Identifier: AGPL-3.0-or-later
4
4
  */
5
- import * as vueUtils from 'eslint-plugin-vue/lib/utils/index.js';
5
+ import { defineTemplateBodyVisitor } from "../../nextcloud-vue/utils/vue-template-visitor.js";
6
6
  import enforceEllipsis from "./enforce-ellipsis.js";
7
7
  const defineRule = (r) => r;
8
8
  export default defineRule({
9
9
  ...enforceEllipsis,
10
10
  create(context) {
11
- return vueUtils.defineTemplateBodyVisitor(context, enforceEllipsis.create(context));
11
+ return defineTemplateBodyVisitor(context, enforceEllipsis.create(context));
12
12
  },
13
13
  });
@@ -2,12 +2,12 @@
2
2
  * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
3
3
  * SPDX-License-Identifier: AGPL-3.0-or-later
4
4
  */
5
- import * as vueUtils from 'eslint-plugin-vue/lib/utils/index.js';
5
+ import { defineTemplateBodyVisitor } from "../../nextcloud-vue/utils/vue-template-visitor.js";
6
6
  import nonBreakingSpace from "./non-breaking-space.js";
7
7
  const defineRule = (r) => r;
8
8
  export default defineRule({
9
9
  ...nonBreakingSpace,
10
10
  create(context) {
11
- return vueUtils.defineTemplateBodyVisitor(context, nonBreakingSpace.create(context));
11
+ return defineTemplateBodyVisitor(context, nonBreakingSpace.create(context));
12
12
  },
13
13
  });
@@ -44,6 +44,9 @@ const ocNested = {
44
44
  scaleFixForIE8: '15.0.0',
45
45
  isIE8: '15.0.0',
46
46
  },
47
+ Settings: {
48
+ UserSettings: '33.0.0',
49
+ },
47
50
  };
48
51
  const oca = {
49
52
  // ref: https://github.com/nextcloud/server/commit/6eced42b7a40f5b0ea0489244583219d0ee2e7af
@@ -51,6 +54,12 @@ const oca = {
51
54
  FilesSharingDrop: '31.0.0',
52
55
  };
53
56
  const ocaNested = {
57
+ Core: {
58
+ ProfileSections: '33.0.0',
59
+ },
60
+ Files: {
61
+ Sidebar: '33.0.0',
62
+ },
54
63
  Sharing: {
55
64
  ExternalLinkActions: '33.0.0',
56
65
  },
@@ -38,7 +38,7 @@ declare const _default: {
38
38
  useModelValueInsteadValue: string;
39
39
  };
40
40
  };
41
- create(context: import("eslint").Rule.RuleContext): any;
41
+ create(context: import("eslint").Rule.RuleContext): import("eslint").Rule.RuleListener;
42
42
  };
43
43
  };
44
44
  meta: {
@@ -33,6 +33,6 @@ export declare const rules: {
33
33
  useModelValueInsteadValue: string;
34
34
  };
35
35
  };
36
- create(context: import("eslint").Rule.RuleContext): any;
36
+ create(context: import("eslint").Rule.RuleContext): import("eslint").Rule.RuleListener;
37
37
  };
38
38
  };
@@ -36,6 +36,6 @@ declare const _default: {
36
36
  useModelValueInsteadValue: string;
37
37
  };
38
38
  };
39
- create(context: Rule.RuleContext): any;
39
+ create(context: Rule.RuleContext): Rule.RuleListener;
40
40
  };
41
41
  export default _default;
@@ -1,5 +1,9 @@
1
- import * as vueUtils from 'eslint-plugin-vue/lib/utils/index.js';
1
+ /*!
2
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
3
+ * SPDX-License-Identifier: AGPL-3.0-or-later
4
+ */
2
5
  import { createLibVersionValidator } from "../utils/lib-version-parser.js";
6
+ import { defineTemplateBodyVisitor } from "../utils/vue-template-visitor.js";
3
7
  export default {
4
8
  meta: {
5
9
  docs: {
@@ -56,7 +60,7 @@ export default {
56
60
  'tertiary',
57
61
  'tertiary-no-background',
58
62
  ];
59
- return vueUtils.defineTemplateBodyVisitor(context, {
63
+ return defineTemplateBodyVisitor(context, {
60
64
  'VElement VAttribute:has(VIdentifier[name="type"])': function (node) {
61
65
  if (![
62
66
  'ncactions',
@@ -72,12 +76,12 @@ export default {
72
76
  return;
73
77
  }
74
78
  const hasNativeType = node.parent.attributes.find((attr) => (attr.key.name === 'native-type'
75
- || (attr.key.type === 'VDirectiveKey' && attr.key.argument && attr.key.argument.name === 'native-type')));
79
+ || (attr.key.type === 'VDirectiveKey' && attr.key.argument && attr.key.argument.type === 'VIdentifier' && attr.key.argument.name === 'native-type')));
76
80
  const isLiteral = node.value.type === 'VLiteral' && legacyTypes.includes(node.value.value);
77
81
  const isExpression = node.value.type === 'VExpressionContainer'
78
82
  && node.value.expression.type === 'ConditionalExpression'
79
- && (legacyTypes.includes(node.value.expression.consequent.value)
80
- || legacyTypes.includes(node.value.expression.alternate.value));
83
+ && (('value' in node.value.expression.consequent && legacyTypes.includes(node.value.expression.consequent.value.toString()))
84
+ || ('value' in node.value.expression.alternate && legacyTypes.includes(node.value.expression.alternate.value.toString())));
81
85
  /**
82
86
  * if it is a literal with a deprecated value -> we migrate
83
87
  * if it is an expression with a defined deprecated value -> we migrate
@@ -290,8 +294,10 @@ export default {
290
294
  return;
291
295
  }
292
296
  const isLiteral = node.value.type === 'VLiteral' && node.value.value === 'arrowRight';
293
- const isExpression = node.value.type === 'VExpressionContainer' && node.value.expression?.type === 'ConditionalExpression'
294
- && (node.value.expression.consequent.value === 'arrowRight' || node.value.expression.alternate.value === 'arrowRight');
297
+ const isExpression = node.value.type === 'VExpressionContainer'
298
+ && node.value.expression?.type === 'ConditionalExpression'
299
+ && (('value' in node.value.expression.consequent && node.value.expression.consequent.value === 'arrowRight')
300
+ || ('value' in node.value.expression.alternate && node.value.expression.alternate.value === 'arrowRight'));
295
301
  /**
296
302
  * if it is a literal with a deprecated value -> we migrate
297
303
  * if it is an expression with a defined deprecated value -> we migrate
@@ -305,9 +311,10 @@ export default {
305
311
  return fixer.replaceTextRange(node.value.range, '"arrowEnd"');
306
312
  }
307
313
  else if (node.key.type === 'VDirectiveKey') {
308
- return (node.value.expression.consequent.value === 'arrowRight')
309
- ? fixer.replaceTextRange(node.value.expression.consequent.range, '\'arrowEnd\'')
310
- : fixer.replaceTextRange(node.value.expression.alternate.range, '\'arrowEnd\'');
314
+ const expression = node.value.expression;
315
+ return expression.consequent.value === 'arrowRight'
316
+ ? fixer.replaceTextRange(expression.consequent.range, '\'arrowEnd\'')
317
+ : fixer.replaceTextRange(expression.alternate.range, '\'arrowEnd\'');
311
318
  }
312
319
  },
313
320
  });
@@ -0,0 +1,26 @@
1
+ /*!
2
+ * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
3
+ * SPDX-License-Identifier: AGPL-3.0-or-later
4
+ */
5
+ import type { Rule } from 'eslint';
6
+ type TemplateVisitor = {
7
+ [key: string]: (...args: unknown[]) => void;
8
+ };
9
+ type TemplateVisitorOptions = {
10
+ templateBodyTriggerSelector: 'Program' | 'Program:exit';
11
+ };
12
+ /**
13
+ * Register the given visitor to parser services.
14
+ * If the parser service of `vue-eslint-parser` was not found,
15
+ * this generates a warning.
16
+ *
17
+ * @param context - The rule context to use parser services.
18
+ * @param templateBodyVisitor - The visitor to traverse the template body.
19
+ * @param scriptVisitor - The visitor to traverse the script.
20
+ * @param options - The options.
21
+ *
22
+ * @return The merged visitor.
23
+ * @see https://github.com/vuejs/eslint-plugin-vue/blob/745fd4e1f3719c3a2f93bd3531da5e886c16f008/lib/utils/index.js#L2281-L2315
24
+ */
25
+ export declare function defineTemplateBodyVisitor(context: Rule.RuleContext, templateBodyVisitor: TemplateVisitor, scriptVisitor?: Rule.RuleListener, options?: TemplateVisitorOptions): Rule.RuleListener;
26
+ export {};
@@ -0,0 +1,36 @@
1
+ /*!
2
+ * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
3
+ * SPDX-License-Identifier: AGPL-3.0-or-later
4
+ */
5
+ import { extname } from 'node:path';
6
+ /**
7
+ * Register the given visitor to parser services.
8
+ * If the parser service of `vue-eslint-parser` was not found,
9
+ * this generates a warning.
10
+ *
11
+ * @param context - The rule context to use parser services.
12
+ * @param templateBodyVisitor - The visitor to traverse the template body.
13
+ * @param scriptVisitor - The visitor to traverse the script.
14
+ * @param options - The options.
15
+ *
16
+ * @return The merged visitor.
17
+ * @see https://github.com/vuejs/eslint-plugin-vue/blob/745fd4e1f3719c3a2f93bd3531da5e886c16f008/lib/utils/index.js#L2281-L2315
18
+ */
19
+ export function defineTemplateBodyVisitor(context, templateBodyVisitor, scriptVisitor, options) {
20
+ const sourceCode = context.sourceCode;
21
+ if (!sourceCode.parserServices?.defineTemplateBodyVisitor) {
22
+ const filename = context.filename;
23
+ if (extname(filename) === '.vue') {
24
+ context.report({
25
+ loc: {
26
+ line: 1,
27
+ column: 0,
28
+ },
29
+ message: 'Use the latest vue-eslint-parser. See also https://eslint.vuejs.org/user-guide/#what-is-the-use-the-latest-vue-eslint-parser-error.',
30
+ });
31
+ }
32
+ return {};
33
+ }
34
+ return sourceCode.parserServices
35
+ .defineTemplateBodyVisitor(templateBodyVisitor, scriptVisitor, options);
36
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextcloud/eslint-config",
3
- "version": "9.0.0-rc.7",
3
+ "version": "9.0.0-rc.8",
4
4
  "description": "Eslint shared config for nextcloud apps and libraries",
5
5
  "keywords": [
6
6
  "eslint",
@@ -44,24 +44,24 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "@eslint/json": "^0.14.0",
47
- "@stylistic/eslint-plugin": "^5.7.0",
47
+ "@stylistic/eslint-plugin": "^5.7.1",
48
48
  "eslint-config-flat-gitignore": "^2.1.0",
49
49
  "eslint-plugin-antfu": "^3.1.3",
50
- "eslint-plugin-jsdoc": "^62.0.0",
51
- "eslint-plugin-perfectionist": "^5.3.1",
52
- "eslint-plugin-vue": "^10.6.2",
50
+ "eslint-plugin-jsdoc": "^62.4.1",
51
+ "eslint-plugin-perfectionist": "^5.4.0",
52
+ "eslint-plugin-vue": "^10.7.0",
53
53
  "fast-xml-parser": "^5.3.3",
54
- "globals": "^17.0.0",
54
+ "globals": "^17.1.0",
55
55
  "semver": "^7.7.3",
56
- "sort-package-json": "^3.6.0",
57
- "typescript-eslint": "^8.53.0"
56
+ "sort-package-json": "^3.6.1",
57
+ "typescript-eslint": "^8.54.0"
58
58
  },
59
59
  "devDependencies": {
60
- "@types/node": "^25.0.6",
60
+ "@types/node": "^25.0.10",
61
61
  "@types/semver": "^7.7.1",
62
62
  "eslint": "^9.39.2",
63
- "memfs": "^4.51.1",
64
- "vitest": "^4.0.17"
63
+ "memfs": "^4.56.10",
64
+ "vitest": "^4.0.18"
65
65
  },
66
66
  "peerDependencies": {
67
67
  "eslint": ">=9"