Skip to content

Commit d314a19

Browse files
committed
feat(#23): add NEXTJS_ROUTE_CASE support for rule folder-naming-convention
1 parent 81417be commit d314a19

File tree

4 files changed

+414
-1
lines changed

4 files changed

+414
-1
lines changed

lib/constants/naming-convention.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,42 @@ const SCREAMING_SNAKE_CASE = '+([A-Z])*([A-Z0-9])*(_+([A-Z0-9]))';
3434
*/
3535
const FLAT_CASE = '+([a-z0-9])';
3636

37+
/**
38+
* @example [helpPageId]
39+
*/
40+
const NEXTJS_DYNAMIC_SEGMENTS = `\\[${CAMEL_CASE}\\]`;
41+
42+
/**
43+
* @example [...auth]
44+
*/
45+
const NEXTJS_CATCH_ALL_SEGMENTS = `\\[...${CAMEL_CASE}\\]`;
46+
47+
/**
48+
* @example [[...auth]]
49+
*/
50+
const NEXTJS_OPTIONAL_CATCH_ALL_SEGMENTS = `\\[\\[...${CAMEL_CASE}\\]\\]`;
51+
52+
/**
53+
* @example (auth)
54+
*/
55+
const NEXTJS_ROUTE_GROUPS = `\\(${KEBAB_CASE}\\)`;
56+
57+
/**
58+
* @example \@feed
59+
*/
60+
const NEXTJS_NAMED_SLOTS = `\\@${KEBAB_CASE}`;
61+
62+
/**
63+
* @example app, [helpPageId], [...auth], [[...auth]], (auth), \@feed
64+
*/
65+
const NEXTJS_ROUTE_CASE = `@(${KEBAB_CASE}|${NEXTJS_DYNAMIC_SEGMENTS}|${NEXTJS_CATCH_ALL_SEGMENTS}|${NEXTJS_OPTIONAL_CATCH_ALL_SEGMENTS}|${NEXTJS_ROUTE_GROUPS}|${NEXTJS_NAMED_SLOTS})`;
66+
3767
module.exports = {
3868
CAMEL_CASE,
3969
PASCAL_CASE,
4070
SNAKE_CASE,
4171
KEBAB_CASE,
4272
SCREAMING_SNAKE_CASE,
4373
FLAT_CASE,
74+
NEXTJS_ROUTE_CASE,
4475
};

lib/rules/folder-naming-convention.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ module.exports = {
7373
continue;
7474
}
7575
for (const path of getSubPaths(folderPath)) {
76-
const matchedPaths = micromatch.capture(folderPattern, path);
76+
const matchedPaths = micromatch.capture(folderPattern, path, {
77+
dot: true,
78+
});
7779

7880
if (isNil(matchedPaths)) continue;
7981

tests/lib/rules/folder-naming-convention.posix.js

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,3 +364,193 @@ ruleTester.run(
364364
],
365365
}
366366
);
367+
368+
ruleTester.run(
369+
"folder-naming-convention with option: [{ 'src/**/': 'NEXTJS_ROUTE_CASE' }]",
370+
rule,
371+
{
372+
valid: [
373+
{
374+
code: "var foo = 'bar';",
375+
filename: 'src/app/page.ts',
376+
options: [{ 'src/**/': 'NEXTJS_ROUTE_CASE' }],
377+
},
378+
{
379+
code: "var foo = 'bar';",
380+
filename: 'src/app/example-route/page.ts',
381+
options: [{ 'src/**/': 'NEXTJS_ROUTE_CASE' }],
382+
},
383+
{
384+
code: "var foo = 'bar';",
385+
filename: 'src/app/users/[userId]/page.ts',
386+
options: [{ 'src/**/': 'NEXTJS_ROUTE_CASE' }],
387+
},
388+
{
389+
code: "var foo = 'bar';",
390+
filename: 'src/app/[...auth]/route.ts',
391+
options: [{ 'src/**/': 'NEXTJS_ROUTE_CASE' }],
392+
},
393+
{
394+
code: "var foo = 'bar';",
395+
filename: 'src/app/shop/[[...shopId]]/page.ts',
396+
options: [{ 'src/**/': 'NEXTJS_ROUTE_CASE' }],
397+
},
398+
{
399+
code: "var foo = 'bar';",
400+
filename: 'src/app/@auth/page.ts',
401+
options: [{ 'src/**/': 'NEXTJS_ROUTE_CASE' }],
402+
},
403+
{
404+
code: "var foo = 'bar';",
405+
filename: 'src/app/(marketing)/page.ts',
406+
options: [{ 'src/**/': 'NEXTJS_ROUTE_CASE' }],
407+
},
408+
],
409+
410+
invalid: [
411+
{
412+
code: "var foo = 'bar';",
413+
filename: 'src/app/exampleRoute/page.ts',
414+
options: [{ 'src/**/': 'NEXTJS_ROUTE_CASE' }],
415+
errors: [
416+
{
417+
message:
418+
'The folder "exampleRoute" does not match the "NEXTJS_ROUTE_CASE" pattern',
419+
column: 1,
420+
line: 1,
421+
},
422+
],
423+
},
424+
{
425+
code: "var foo = 'bar';",
426+
filename: 'src/app/users/[userId/page.ts',
427+
options: [{ 'src/**/': 'NEXTJS_ROUTE_CASE' }],
428+
errors: [
429+
{
430+
message:
431+
'The folder "[userId" does not match the "NEXTJS_ROUTE_CASE" pattern',
432+
column: 1,
433+
line: 1,
434+
},
435+
],
436+
},
437+
{
438+
code: "var foo = 'bar';",
439+
filename: 'src/app/users/userId]/page.ts',
440+
options: [{ 'src/**/': 'NEXTJS_ROUTE_CASE' }],
441+
errors: [
442+
{
443+
message:
444+
'The folder "userId]" does not match the "NEXTJS_ROUTE_CASE" pattern',
445+
column: 1,
446+
line: 1,
447+
},
448+
],
449+
},
450+
{
451+
code: "var foo = 'bar';",
452+
filename: 'src/app/[..auth]/route.ts',
453+
options: [{ 'src/**/': 'NEXTJS_ROUTE_CASE' }],
454+
errors: [
455+
{
456+
message:
457+
'The folder "[..auth]" does not match the "NEXTJS_ROUTE_CASE" pattern',
458+
column: 1,
459+
line: 1,
460+
},
461+
],
462+
},
463+
{
464+
code: "var foo = 'bar';",
465+
filename: 'src/app/[...auth/route.ts',
466+
options: [{ 'src/**/': 'NEXTJS_ROUTE_CASE' }],
467+
errors: [
468+
{
469+
message:
470+
'The folder "[...auth" does not match the "NEXTJS_ROUTE_CASE" pattern',
471+
column: 1,
472+
line: 1,
473+
},
474+
],
475+
},
476+
{
477+
code: "var foo = 'bar';",
478+
filename: 'src/app/...auth]/route.ts',
479+
options: [{ 'src/**/': 'NEXTJS_ROUTE_CASE' }],
480+
errors: [
481+
{
482+
message:
483+
'The folder "...auth]" does not match the "NEXTJS_ROUTE_CASE" pattern',
484+
column: 1,
485+
line: 1,
486+
},
487+
],
488+
},
489+
{
490+
code: "var foo = 'bar';",
491+
filename: 'src/app/shop/[[...shopId]/page.ts',
492+
options: [{ 'src/**/': 'NEXTJS_ROUTE_CASE' }],
493+
errors: [
494+
{
495+
message:
496+
'The folder "[[...shopId]" does not match the "NEXTJS_ROUTE_CASE" pattern',
497+
column: 1,
498+
line: 1,
499+
},
500+
],
501+
},
502+
{
503+
code: "var foo = 'bar';",
504+
filename: 'src/app/shop/[...shopId]]/page.ts',
505+
options: [{ 'src/**/': 'NEXTJS_ROUTE_CASE' }],
506+
errors: [
507+
{
508+
message:
509+
'The folder "[...shopId]]" does not match the "NEXTJS_ROUTE_CASE" pattern',
510+
column: 1,
511+
line: 1,
512+
},
513+
],
514+
},
515+
{
516+
code: "var foo = 'bar';",
517+
filename: 'src/app/shop/[[..shopId]]/page.ts',
518+
options: [{ 'src/**/': 'NEXTJS_ROUTE_CASE' }],
519+
errors: [
520+
{
521+
message:
522+
'The folder "[[..shopId]]" does not match the "NEXTJS_ROUTE_CASE" pattern',
523+
column: 1,
524+
line: 1,
525+
},
526+
],
527+
},
528+
{
529+
code: "var foo = 'bar';",
530+
filename: 'src/app/@authMarker/page.ts',
531+
options: [{ 'src/**/': 'NEXTJS_ROUTE_CASE' }],
532+
errors: [
533+
{
534+
message:
535+
'The folder "@authMarker" does not match the "NEXTJS_ROUTE_CASE" pattern',
536+
column: 1,
537+
line: 1,
538+
},
539+
],
540+
},
541+
{
542+
code: "var foo = 'bar';",
543+
filename: 'src/app/(marketingSpeak)/page.ts',
544+
options: [{ 'src/**/': 'NEXTJS_ROUTE_CASE' }],
545+
errors: [
546+
{
547+
message:
548+
'The folder "(marketingSpeak)" does not match the "NEXTJS_ROUTE_CASE" pattern',
549+
column: 1,
550+
line: 1,
551+
},
552+
],
553+
},
554+
],
555+
}
556+
);

0 commit comments

Comments
 (0)