@next/eslint-plugin-next 15.0.0-rc.0 → 15.0.0

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.
@@ -12,6 +12,9 @@ function _array_like_to_array(arr, len) {
12
12
  function _array_with_holes(arr) {
13
13
  if (Array.isArray(arr)) return arr;
14
14
  }
15
+ function _array_without_holes(arr) {
16
+ if (Array.isArray(arr)) return _array_like_to_array(arr);
17
+ }
15
18
  function _getRequireWildcardCache(nodeInterop) {
16
19
  if (typeof WeakMap !== "function") return null;
17
20
  var cacheBabelInterop = new WeakMap();
@@ -53,6 +56,9 @@ function _interop_require_wildcard(obj, nodeInterop) {
53
56
  }
54
57
  return newObj;
55
58
  }
59
+ function _iterable_to_array(iter) {
60
+ if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
61
+ }
56
62
  function _iterable_to_array_limit(arr, i) {
57
63
  var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
58
64
  if (_i == null) return;
@@ -80,9 +86,15 @@ function _iterable_to_array_limit(arr, i) {
80
86
  function _non_iterable_rest() {
81
87
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
82
88
  }
89
+ function _non_iterable_spread() {
90
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
91
+ }
83
92
  function _sliced_to_array(arr, i) {
84
93
  return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
85
94
  }
95
+ function _to_consumable_array(arr) {
96
+ return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
97
+ }
86
98
  function _unsupported_iterable_to_array(o, minLen) {
87
99
  if (!o) return;
88
100
  if (typeof o === "string") return _array_like_to_array(o, minLen);
@@ -162,6 +174,8 @@ module.exports = (0, _definerule.defineRule)({
162
174
  return {};
163
175
  }
164
176
  var pageUrls = (0, _url.getUrlFromPagesDirectories)('/', foundPagesDirs);
177
+ var appDirUrls = (0, _url.getUrlFromAppDirectory)('/', foundAppDirs);
178
+ var allUrls = _to_consumable_array(pageUrls).concat(_to_consumable_array(appDirUrls));
165
179
  return {
166
180
  JSXOpeningElement: function JSXOpeningElement(node) {
167
181
  if (node.name.name !== 'a') {
@@ -193,8 +207,8 @@ module.exports = (0, _definerule.defineRule)({
193
207
  if (/^(https?:\/\/|\/\/)/.test(hrefPath)) {
194
208
  return;
195
209
  }
196
- pageUrls.forEach(function(pageUrl) {
197
- if (pageUrl.test((0, _url.normalizeURL)(hrefPath))) {
210
+ allUrls.forEach(function(foundUrl) {
211
+ if (foundUrl.test((0, _url.normalizeURL)(hrefPath))) {
198
212
  context.report({
199
213
  node: node,
200
214
  message: "Do not use an `<a>` element to navigate to `".concat(hrefPath, "`. Use `<Link />` from `next/link` instead. See: ").concat(url)
@@ -8,13 +8,13 @@ Object.defineProperty(exports, "getRootDirs", {
8
8
  return getRootDirs;
9
9
  }
10
10
  });
11
- var _glob = require("glob");
11
+ var _fastglob = require("fast-glob");
12
12
  /**
13
13
  * Process a Next.js root directory glob.
14
14
  */ var processRootDir = function(rootDir) {
15
- // Ensures we only match folders.
16
- if (!rootDir.endsWith('/')) rootDir += '/';
17
- return (0, _glob.globSync)(rootDir);
15
+ return (0, _fastglob.globSync)(rootDir.replace(/\\/g, '/'), {
16
+ onlyDirectories: true
17
+ });
18
18
  };
19
19
  var getRootDirs = function(context) {
20
20
  var rootDirs = [
package/dist/utils/url.js CHANGED
@@ -12,9 +12,15 @@ _export(exports, {
12
12
  execOnce: function() {
13
13
  return execOnce;
14
14
  },
15
+ getUrlFromAppDirectory: function() {
16
+ return getUrlFromAppDirectory;
17
+ },
15
18
  getUrlFromPagesDirectories: function() {
16
19
  return getUrlFromPagesDirectories;
17
20
  },
21
+ normalizeAppPath: function() {
22
+ return normalizeAppPath;
23
+ },
18
24
  normalizeURL: function() {
19
25
  return normalizeURL;
20
26
  }
@@ -117,6 +123,34 @@ var fsReadDirSyncCache = {};
117
123
  });
118
124
  return res;
119
125
  }
126
+ /**
127
+ * Recursively parse app directory for URLs.
128
+ */ function parseUrlForAppDir(urlprefix, directory) {
129
+ var _fsReadDirSyncCache, _directory;
130
+ var _;
131
+ (_ = (_fsReadDirSyncCache = fsReadDirSyncCache)[_directory = directory]) !== null && _ !== void 0 ? _ : _fsReadDirSyncCache[_directory] = _fs.readdirSync(directory, {
132
+ withFileTypes: true
133
+ });
134
+ var res = [];
135
+ fsReadDirSyncCache[directory].forEach(function(dirent) {
136
+ // TODO: this should account for all page extensions
137
+ // not just js(x) and ts(x)
138
+ if (/(\.(j|t)sx?)$/.test(dirent.name)) {
139
+ if (/^page(\.(j|t)sx?)$/.test(dirent.name)) {
140
+ res.push("".concat(urlprefix).concat(dirent.name.replace(/^page(\.(j|t)sx?)$/, '')));
141
+ } else if (!/^layout(\.(j|t)sx?)$/.test(dirent.name)) {
142
+ res.push("".concat(urlprefix).concat(dirent.name.replace(/(\.(j|t)sx?)$/, '')));
143
+ }
144
+ } else {
145
+ var dirPath = _path.join(directory, dirent.name);
146
+ if (dirent.isDirectory(dirPath) && !dirent.isSymbolicLink()) {
147
+ var _res;
148
+ (_res = res).push.apply(_res, _to_consumable_array(parseUrlForPages(urlprefix + dirent.name + '/', dirPath)));
149
+ }
150
+ }
151
+ });
152
+ return res;
153
+ }
120
154
  function normalizeURL(url) {
121
155
  if (!url) {
122
156
  return;
@@ -131,6 +165,27 @@ function normalizeURL(url) {
131
165
  url = url.endsWith('/') ? url : url + '/';
132
166
  return url;
133
167
  }
168
+ function normalizeAppPath(route) {
169
+ return ensureLeadingSlash(route.split('/').reduce(function(pathname, segment, index, segments) {
170
+ // Empty segments are ignored.
171
+ if (!segment) {
172
+ return pathname;
173
+ }
174
+ // Groups are ignored.
175
+ if (isGroupSegment(segment)) {
176
+ return pathname;
177
+ }
178
+ // Parallel segments are ignored.
179
+ if (segment[0] === '@') {
180
+ return pathname;
181
+ }
182
+ // The last segment (if it's a leaf) should be ignored.
183
+ if ((segment === 'page' || segment === 'route') && index === segments.length - 1) {
184
+ return pathname;
185
+ }
186
+ return "".concat(pathname, "/").concat(segment);
187
+ }, ''));
188
+ }
134
189
  function getUrlFromPagesDirectories(urlPrefix, directories) {
135
190
  return Array.from(// De-duplicate similar pages across multiple directories.
136
191
  new Set(directories.flatMap(function(directory) {
@@ -143,6 +198,18 @@ function getUrlFromPagesDirectories(urlPrefix, directories) {
143
198
  return new RegExp(urlReg);
144
199
  });
145
200
  }
201
+ function getUrlFromAppDirectory(urlPrefix, directories) {
202
+ return Array.from(// De-duplicate similar pages across multiple directories.
203
+ new Set(directories.map(function(directory) {
204
+ return parseUrlForAppDir(urlPrefix, directory);
205
+ }).flat().map(// Since the URLs are normalized we add `^` and `$` to the RegExp to make sure they match exactly.
206
+ function(url) {
207
+ return "^".concat(normalizeAppPath(url), "$");
208
+ }))).map(function(urlReg) {
209
+ urlReg = urlReg.replace(/\[.*\]/g, '((?!.+?\\..+?).*?)');
210
+ return new RegExp(urlReg);
211
+ });
212
+ }
146
213
  function execOnce(fn) {
147
214
  var used = false;
148
215
  var result;
@@ -157,3 +224,9 @@ function execOnce(fn) {
157
224
  return result;
158
225
  };
159
226
  }
227
+ function ensureLeadingSlash(route) {
228
+ return route.startsWith('/') ? route : "/".concat(route);
229
+ }
230
+ function isGroupSegment(segment) {
231
+ return segment[0] === '(' && segment.endsWith(')');
232
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@next/eslint-plugin-next",
3
- "version": "15.0.0-rc.0",
3
+ "version": "15.0.0",
4
4
  "description": "ESLint plugin for Next.js.",
5
5
  "main": "dist/index.js",
6
6
  "license": "MIT",
@@ -12,7 +12,7 @@
12
12
  "dist"
13
13
  ],
14
14
  "dependencies": {
15
- "glob": "10.3.10"
15
+ "fast-glob": "3.3.1"
16
16
  },
17
17
  "devDependencies": {
18
18
  "eslint": "8.56.0"