@rikalabs/repo-lint 0.2.5 → 0.3.1

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.
@@ -0,0 +1 @@
1
+ export { directory, DirNode, DirOptions, LayoutNode } from '../types/index';
@@ -0,0 +1 @@
1
+ module.exports.directory = require('../index.js').directory;
@@ -0,0 +1 @@
1
+ export { file, FileNode, FileOptions, CaseStyle } from '../types/index';
package/file/index.js ADDED
@@ -0,0 +1 @@
1
+ module.exports.file = require('../index.js').file;
package/index.js CHANGED
@@ -1,16 +1,45 @@
1
1
  module.exports.defineConfig = (config) => config;
2
- module.exports.dir = (children) => ({ type: "dir", children: children || {} });
3
- module.exports.file = (pattern) => ({ type: "file", pattern });
4
- module.exports.opt = (node) => ({ ...node, optional: true });
2
+
3
+ const directory = (children, options) => ({
4
+ type: "dir",
5
+ children: children || {},
6
+ ...(options?.strict && { strict: true }),
7
+ ...(options?.maxDepth !== undefined && { maxDepth: options.maxDepth }),
8
+ });
9
+ module.exports.directory = directory;
10
+ module.exports.dir = directory;
11
+
12
+ const file = (patternOrOptions) => {
13
+ if (typeof patternOrOptions === "string" || patternOrOptions === undefined) {
14
+ return { type: "file", pattern: patternOrOptions };
15
+ }
16
+ return {
17
+ type: "file",
18
+ pattern: patternOrOptions.pattern,
19
+ ...(patternOrOptions.case && { case: patternOrOptions.case }),
20
+ };
21
+ };
22
+ module.exports.file = file;
23
+
24
+ const optional = (node) => ({ ...node, optional: true });
25
+ module.exports.optional = optional;
26
+ module.exports.opt = optional;
27
+
28
+ const required = (node) => ({ ...node, required: true });
29
+ module.exports.required = required;
30
+
5
31
  module.exports.param = (opts, child) => ({ type: "param", ...opts, child });
32
+
6
33
  module.exports.many = (optsOrChild, child) => {
7
34
  if (child) return { type: "many", ...optsOrChild, child };
8
35
  return { type: "many", child: optsOrChild };
9
36
  };
37
+
10
38
  module.exports.recursive = (optsOrChild, child) => {
11
39
  if (child) return { type: "recursive", ...optsOrChild, child };
12
40
  return { type: "recursive", maxDepth: 10, child: optsOrChild };
13
41
  };
42
+
14
43
  module.exports.either = (...variants) => ({ type: "either", variants });
15
44
 
16
45
  const presets = require('./presets/index.js');
@@ -0,0 +1 @@
1
+ export { optional, LayoutNode } from '../types/index';
@@ -0,0 +1 @@
1
+ module.exports.optional = require('../index.js').optional;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rikalabs/repo-lint",
3
- "version": "0.2.5",
3
+ "version": "0.3.1",
4
4
  "description": "High-performance filesystem layout linter with TypeScript DSL config",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -22,6 +22,38 @@
22
22
  ],
23
23
  "main": "index.js",
24
24
  "types": "types/index.d.ts",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./types/index.d.ts",
28
+ "require": "./index.js",
29
+ "import": "./index.js"
30
+ },
31
+ "./directory": {
32
+ "types": "./directory/index.d.ts",
33
+ "require": "./directory/index.js",
34
+ "import": "./directory/index.js"
35
+ },
36
+ "./optional": {
37
+ "types": "./optional/index.d.ts",
38
+ "require": "./optional/index.js",
39
+ "import": "./optional/index.js"
40
+ },
41
+ "./required": {
42
+ "types": "./required/index.d.ts",
43
+ "require": "./required/index.js",
44
+ "import": "./required/index.js"
45
+ },
46
+ "./file": {
47
+ "types": "./file/index.d.ts",
48
+ "require": "./file/index.js",
49
+ "import": "./file/index.js"
50
+ },
51
+ "./presets": {
52
+ "types": "./presets/index.d.ts",
53
+ "require": "./presets/index.js",
54
+ "import": "./presets/index.js"
55
+ }
56
+ },
25
57
  "bin": {
26
58
  "repo-lint": "./bin/repo-lint"
27
59
  },
@@ -30,7 +62,11 @@
30
62
  "install.js",
31
63
  "bin",
32
64
  "types",
33
- "presets"
65
+ "presets",
66
+ "directory",
67
+ "optional",
68
+ "required",
69
+ "file"
34
70
  ],
35
71
  "scripts": {
36
72
  "postinstall": "node install.js"
@@ -0,0 +1 @@
1
+ export { required, LayoutNode } from '../types/index';
@@ -0,0 +1 @@
1
+ module.exports.required = require('../index.js').required;
package/types/index.d.ts CHANGED
@@ -1,3 +1,15 @@
1
+ export type CaseStyle = "kebab" | "snake" | "camel" | "pascal" | "any";
2
+
3
+ export interface MirrorConfig {
4
+ source: string;
5
+ target: string;
6
+ pattern: string;
7
+ }
8
+
9
+ export interface WhenRequirement {
10
+ requires: string[];
11
+ }
12
+
1
13
  export interface DefineConfigOptions {
2
14
  mode?: "strict" | "warn";
3
15
  layout: LayoutNode;
@@ -6,6 +18,14 @@ export interface DefineConfigOptions {
6
18
  deps?: DepsConfig;
7
19
  ignore?: string[];
8
20
  useGitignore?: boolean;
21
+ /** Glob patterns to discover workspace configs (e.g., ["apps/*", "packages/*"]) */
22
+ workspaces?: string[];
23
+ /** File dependency rules: source glob -> target glob */
24
+ dependencies?: Record<string, string>;
25
+ /** Mirror structure rules */
26
+ mirror?: MirrorConfig[];
27
+ /** Conditional requirements: if file exists, require others */
28
+ when?: Record<string, WhenRequirement>;
9
29
  }
10
30
 
11
31
  export type LayoutNode =
@@ -16,16 +36,33 @@ export type LayoutNode =
16
36
  | RecursiveNode
17
37
  | EitherNode;
18
38
 
39
+ export interface DirOptions {
40
+ /** Reject files not matching any defined pattern */
41
+ strict?: boolean;
42
+ /** Maximum allowed nesting depth */
43
+ maxDepth?: number;
44
+ }
45
+
19
46
  export interface DirNode {
20
47
  type: "dir";
21
48
  children: Record<string, LayoutNode>;
22
49
  optional?: boolean;
50
+ required?: boolean;
51
+ strict?: boolean;
52
+ maxDepth?: number;
53
+ }
54
+
55
+ export interface FileOptions {
56
+ pattern?: string;
57
+ case?: CaseStyle;
23
58
  }
24
59
 
25
60
  export interface FileNode {
26
61
  type: "file";
27
62
  pattern?: string;
28
63
  optional?: boolean;
64
+ required?: boolean;
65
+ case?: CaseStyle;
29
66
  }
30
67
 
31
68
  export interface ParamNode {
@@ -39,6 +76,7 @@ export interface ManyNode {
39
76
  type: "many";
40
77
  case?: CaseStyle;
41
78
  child: LayoutNode;
79
+ max?: number;
42
80
  }
43
81
 
44
82
  export interface RecursiveNode {
@@ -52,9 +90,8 @@ export interface EitherNode {
52
90
  variants: LayoutNode[];
53
91
  }
54
92
 
55
- export type CaseStyle = "kebab" | "snake" | "camel" | "pascal" | "any";
56
-
57
93
  export interface RulesConfig {
94
+ /** Glob patterns for forbidden paths (supports ! negation) */
58
95
  forbidPaths?: string[];
59
96
  forbidNames?: string[];
60
97
  ignorePaths?: string[];
@@ -77,21 +114,44 @@ export interface DepsConfig {
77
114
 
78
115
  export function defineConfig(options: DefineConfigOptions): DefineConfigOptions;
79
116
 
80
- export function dir(children?: Record<string, LayoutNode>): DirNode;
117
+ /** Create a directory node */
118
+ export function directory(
119
+ children?: Record<string, LayoutNode>,
120
+ options?: DirOptions
121
+ ): DirNode;
122
+ /** @deprecated Use `directory` instead */
123
+ export function dir(
124
+ children?: Record<string, LayoutNode>,
125
+ options?: DirOptions
126
+ ): DirNode;
127
+
128
+ /** Create a file node */
81
129
  export function file(pattern?: string): FileNode;
130
+ export function file(options: FileOptions): FileNode;
131
+
132
+ /** Mark a node as optional (may or may not exist) */
133
+ export function optional<T extends LayoutNode>(node: T): T & { optional: true };
134
+ /** @deprecated Use `optional` instead */
82
135
  export function opt<T extends LayoutNode>(node: T): T & { optional: true };
136
+
137
+ /** Mark a node as required (must exist, error if missing) */
138
+ export function required<T extends LayoutNode>(node: T): T & { required: true };
139
+
83
140
  export function param(
84
141
  options: { case: CaseStyle; name?: string },
85
142
  child: LayoutNode
86
143
  ): ParamNode;
144
+
87
145
  export function many(
88
- options: { case?: CaseStyle } | LayoutNode,
146
+ options: { case?: CaseStyle; max?: number } | LayoutNode,
89
147
  child?: LayoutNode
90
148
  ): ManyNode;
149
+
91
150
  export function recursive(
92
151
  options: { maxDepth?: number } | LayoutNode,
93
152
  child?: LayoutNode
94
153
  ): RecursiveNode;
154
+
95
155
  export function either(...variants: LayoutNode[]): EitherNode;
96
156
 
97
157
  export interface NextjsAppRouterOptions {