@rikalabs/repo-lint 0.1.0 → 0.2.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.
package/index.js CHANGED
@@ -7,3 +7,13 @@ module.exports.many = (optsOrChild, child) => {
7
7
  if (child) return { type: "many", ...optsOrChild, child };
8
8
  return { type: "many", child: optsOrChild };
9
9
  };
10
+ module.exports.recursive = (optsOrChild, child) => {
11
+ if (child) return { type: "recursive", ...optsOrChild, child };
12
+ return { type: "recursive", maxDepth: 10, child: optsOrChild };
13
+ };
14
+ module.exports.either = (...variants) => ({ type: "either", variants });
15
+
16
+ const presets = require('./presets/index.js');
17
+ module.exports.nextjsAppRouter = presets.nextjsAppRouter;
18
+ module.exports.nextjsDefaultIgnore = presets.nextjsDefaultIgnore;
19
+ module.exports.nextjsDefaultIgnorePaths = presets.nextjsDefaultIgnorePaths;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rikalabs/repo-lint",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "High-performance filesystem layout linter with TypeScript DSL config",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -29,7 +29,8 @@
29
29
  "index.js",
30
30
  "install.js",
31
31
  "bin",
32
- "types"
32
+ "types",
33
+ "presets"
33
34
  ],
34
35
  "scripts": {
35
36
  "postinstall": "node install.js"
@@ -0,0 +1,11 @@
1
+ const {
2
+ nextjsAppRouter,
3
+ nextjsDefaultIgnore,
4
+ nextjsDefaultIgnorePaths,
5
+ } = require('./nextjs.js');
6
+
7
+ module.exports = {
8
+ nextjsAppRouter,
9
+ nextjsDefaultIgnore,
10
+ nextjsDefaultIgnorePaths,
11
+ };
@@ -0,0 +1,97 @@
1
+ const { dir, file, opt, param, many, recursive, either } = require('../index.js');
2
+
3
+ function nextjsAppRouter(options = {}) {
4
+ const routeCase = options.routeCase ?? 'kebab';
5
+ const maxDepth = options.maxDepth ?? 10;
6
+
7
+ const routeFiles = dir({
8
+ 'page.tsx': opt(file()),
9
+ 'layout.tsx': opt(file()),
10
+ 'loading.tsx': opt(file()),
11
+ 'error.tsx': opt(file()),
12
+ 'not-found.tsx': opt(file()),
13
+ 'template.tsx': opt(file()),
14
+ 'default.tsx': opt(file()),
15
+ 'route.ts': opt(file()),
16
+ 'opengraph-image.tsx': opt(file()),
17
+ 'twitter-image.tsx': opt(file()),
18
+ 'sitemap.ts': opt(file()),
19
+ 'robots.ts': opt(file()),
20
+ });
21
+
22
+ return dir({
23
+ src: opt(dir({
24
+ app: dir({
25
+ $routes: recursive(
26
+ { maxDepth },
27
+ param({ case: routeCase }, routeFiles)
28
+ ),
29
+ 'layout.tsx': file(),
30
+ 'page.tsx': opt(file()),
31
+ 'globals.css': opt(file()),
32
+ }),
33
+ components: opt(dir({
34
+ $component: many(
35
+ { case: 'pascal' },
36
+ either(
37
+ file('*.tsx'),
38
+ dir({
39
+ 'index.tsx': file(),
40
+ $files: many(file('*.tsx')),
41
+ })
42
+ )
43
+ ),
44
+ })),
45
+ lib: opt(dir({
46
+ $file: many(file('*.ts')),
47
+ })),
48
+ hooks: opt(dir({
49
+ $hook: many(file('use*.ts')),
50
+ })),
51
+ styles: opt(dir({
52
+ $style: many(file('*.css')),
53
+ })),
54
+ })),
55
+ app: opt(dir({
56
+ $routes: recursive(
57
+ { maxDepth },
58
+ param({ case: routeCase }, routeFiles)
59
+ ),
60
+ 'layout.tsx': file(),
61
+ 'page.tsx': opt(file()),
62
+ 'globals.css': opt(file()),
63
+ })),
64
+ public: opt(dir({
65
+ $asset: many(file()),
66
+ })),
67
+ 'next.config.js': opt(file()),
68
+ 'next.config.mjs': opt(file()),
69
+ 'next.config.ts': opt(file()),
70
+ 'tailwind.config.js': opt(file()),
71
+ 'tailwind.config.ts': opt(file()),
72
+ 'postcss.config.js': opt(file()),
73
+ 'postcss.config.mjs': opt(file()),
74
+ 'tsconfig.json': opt(file()),
75
+ 'package.json': file(),
76
+ });
77
+ }
78
+
79
+ function nextjsDefaultIgnore() {
80
+ return ['.next', 'node_modules', '.turbo', 'out', '.vercel'];
81
+ }
82
+
83
+ function nextjsDefaultIgnorePaths() {
84
+ return [
85
+ '**/.next/**',
86
+ '**/node_modules/**',
87
+ '**/.turbo/**',
88
+ '**/out/**',
89
+ '**/.vercel/**',
90
+ ];
91
+ }
92
+
93
+ module.exports = {
94
+ nextjsAppRouter,
95
+ nextjsDefaultIgnore,
96
+ nextjsDefaultIgnorePaths,
97
+ };
package/types/index.d.ts CHANGED
@@ -4,13 +4,17 @@ export interface DefineConfigOptions {
4
4
  rules?: RulesConfig;
5
5
  boundaries?: BoundariesConfig;
6
6
  deps?: DepsConfig;
7
+ ignore?: string[];
8
+ useGitignore?: boolean;
7
9
  }
8
10
 
9
11
  export type LayoutNode =
10
12
  | DirNode
11
13
  | FileNode
12
14
  | ParamNode
13
- | ManyNode;
15
+ | ManyNode
16
+ | RecursiveNode
17
+ | EitherNode;
14
18
 
15
19
  export interface DirNode {
16
20
  type: "dir";
@@ -37,11 +41,23 @@ export interface ManyNode {
37
41
  child: LayoutNode;
38
42
  }
39
43
 
44
+ export interface RecursiveNode {
45
+ type: "recursive";
46
+ maxDepth?: number;
47
+ child: LayoutNode;
48
+ }
49
+
50
+ export interface EitherNode {
51
+ type: "either";
52
+ variants: LayoutNode[];
53
+ }
54
+
40
55
  export type CaseStyle = "kebab" | "snake" | "camel" | "pascal" | "any";
41
56
 
42
57
  export interface RulesConfig {
43
58
  forbidPaths?: string[];
44
59
  forbidNames?: string[];
60
+ ignorePaths?: string[];
45
61
  }
46
62
 
47
63
  export interface BoundariesConfig {
@@ -72,3 +88,17 @@ export function many(
72
88
  options: { case?: CaseStyle } | LayoutNode,
73
89
  child?: LayoutNode
74
90
  ): ManyNode;
91
+ export function recursive(
92
+ options: { maxDepth?: number } | LayoutNode,
93
+ child?: LayoutNode
94
+ ): RecursiveNode;
95
+ export function either(...variants: LayoutNode[]): EitherNode;
96
+
97
+ export interface NextjsAppRouterOptions {
98
+ routeCase?: CaseStyle;
99
+ maxDepth?: number;
100
+ }
101
+
102
+ export function nextjsAppRouter(options?: NextjsAppRouterOptions): DirNode;
103
+ export function nextjsDefaultIgnore(): string[];
104
+ export function nextjsDefaultIgnorePaths(): string[];