directory-lint 2.0.2 → 2.0.3

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/dist/index.cjs CHANGED
@@ -91,35 +91,48 @@ var DirectoryLint = class {
91
91
  cwd,
92
92
  paths: {}
93
93
  };
94
- if (!this.backend.exists(cwd)) this.backend.makeDirectory(cwd, options?.recursive);
94
+ if (!this.backend.exists(cwd)) {
95
+ this.backend.makeDirectory(cwd, options?.recursive);
96
+ }
95
97
  for (const [name, node] of Object.entries(schema)) {
96
98
  const isRegexLiteral = name.startsWith("/") && name.endsWith("/");
97
99
  if (isRegexLiteral) throw new RegexNotSupported(name);
98
100
  const fullPath = (0, import_path.join)(cwd, name);
99
101
  if (node.type === "directory") {
100
- let childrenResult = void 0;
102
+ let childrenResult;
101
103
  if (!this.backend.exists(fullPath)) {
102
104
  this.backend.makeDirectory(fullPath, options?.recursive);
103
105
  }
104
106
  if (node.children) {
105
- childrenResult = await this.generate(fullPath, node.children, options);
107
+ childrenResult = await this.generate(
108
+ fullPath,
109
+ node.children,
110
+ options
111
+ );
106
112
  }
107
113
  result.paths[name] = {
108
- type: node.type,
114
+ type: "directory",
109
115
  path: fullPath,
110
- ...childrenResult?.paths && { children: childrenResult.paths }
116
+ ...childrenResult?.paths && {
117
+ children: childrenResult.paths
118
+ }
111
119
  };
112
- } else if (node.type === "file") {
120
+ }
121
+ if (node.type === "file") {
113
122
  if (!this.backend.exists(fullPath)) {
114
- this.backend.writeFile(fullPath, node.content === void 0 ? "" : node.content);
115
- } else {
116
- if (options?.overwrite) {
117
- this.backend.writeFile(fullPath, node.content === void 0 ? "" : node.content);
118
- }
123
+ this.backend.writeFile(
124
+ fullPath,
125
+ node.content ?? ""
126
+ );
127
+ } else if (options?.overwrite) {
128
+ this.backend.writeFile(
129
+ fullPath,
130
+ node.content ?? ""
131
+ );
119
132
  }
120
133
  result.paths[name] = {
121
- path: fullPath,
122
- type: node.type
134
+ type: "file",
135
+ path: fullPath
123
136
  };
124
137
  }
125
138
  }
@@ -133,39 +146,54 @@ var DirectoryLint = class {
133
146
  const items = this.backend.getAllItems(cwd);
134
147
  const processedNames = /* @__PURE__ */ new Set();
135
148
  const sortedEntries = Object.entries(schema).sort(([a], [b]) => {
136
- const aHasWildcard = a.includes("*");
137
- const bHasWildcard = b.includes("*");
149
+ const aHasWildcard = String(a).includes("*");
150
+ const bHasWildcard = String(b).includes("*");
138
151
  if (!aHasWildcard && bHasWildcard) return -1;
139
152
  if (aHasWildcard && !bHasWildcard) return 1;
140
153
  return 0;
141
154
  });
142
155
  for (const [pattern, node] of sortedEntries) {
143
- const regex = this.patternToRegex(pattern);
156
+ const regex = this.patternToRegex(String(pattern));
144
157
  const matchedItems = items.filter(
145
158
  (item) => regex.test(item.name) && !processedNames.has(item.name)
146
159
  );
147
160
  const isRequired = node.required ?? true;
148
- if (matchedItems.length === 0 && isRequired) throw new InvalidStructure(pattern);
161
+ if (matchedItems.length === 0 && isRequired) {
162
+ throw new InvalidStructure(String(pattern));
163
+ }
149
164
  for (const { name, type } of matchedItems) {
150
165
  if (options?.ignore.includes(name)) continue;
151
166
  processedNames.add(name);
152
167
  const fullPath = (0, import_path.join)(cwd, name);
153
168
  if (node.type === "directory") {
154
- if (type !== "directory") throw new InvalidStructure(fullPath);
155
- let childrenResult = void 0;
169
+ if (type !== "directory") {
170
+ throw new InvalidStructure(fullPath);
171
+ }
172
+ let childrenResult;
156
173
  if (node.children) {
157
- childrenResult = await this.validate(fullPath, node.children, options);
174
+ childrenResult = await this.validate(
175
+ fullPath,
176
+ node.children,
177
+ options
178
+ );
158
179
  }
159
180
  result.paths[name] = {
160
181
  path: fullPath,
161
182
  name,
162
183
  type: "directory",
163
- ...childrenResult?.paths && { children: childrenResult.paths }
184
+ ...childrenResult?.paths && {
185
+ children: childrenResult.paths
186
+ }
164
187
  };
165
- } else if (node.type === "file") {
166
- if (type !== "file") throw new InvalidStructure(fullPath);
188
+ }
189
+ if (node.type === "file") {
190
+ if (type !== "file") {
191
+ throw new InvalidStructure(fullPath);
192
+ }
167
193
  const content = this.backend.readFile(fullPath);
168
- if (node.validate ? !node.validate(content) : false) throw new InvalidContent(fullPath);
194
+ if (node.validate && !node.validate(content)) {
195
+ throw new InvalidContent(fullPath);
196
+ }
169
197
  result.paths[name] = {
170
198
  path: fullPath,
171
199
  name,
package/dist/index.d.cts CHANGED
@@ -44,6 +44,16 @@ interface LintBackend {
44
44
  exists(path: string): boolean;
45
45
  }
46
46
 
47
+ type MapValidateSchema<T> = {
48
+ [K in keyof T]: T[K] extends {
49
+ type: "file";
50
+ } ? ValidateFileResult : T[K] extends {
51
+ type: "directory";
52
+ children?: infer C;
53
+ } ? ValidateDirectoryResult & {
54
+ children: C extends object ? MapValidateSchema<C> : undefined;
55
+ } : never;
56
+ };
47
57
  interface GenerateOptions {
48
58
  overwrite?: boolean;
49
59
  recursive?: boolean;
@@ -64,9 +74,9 @@ interface ValidateDirectoryResult {
64
74
  }
65
75
  type ValidateNodeResult = ValidateFileResult | ValidateDirectoryResult;
66
76
  type ValidatePathResult = Record<string, ValidateNodeResult>;
67
- interface ValidateResult {
77
+ interface ValidateResult<TSchema> {
68
78
  cwd: string;
69
- paths: ValidatePathResult;
79
+ paths: MapValidateSchema<TSchema>;
70
80
  }
71
81
  interface GenerateFileResult {
72
82
  type: "file";
@@ -88,7 +98,7 @@ declare class DirectoryLint {
88
98
  private readonly backend;
89
99
  constructor(backend?: LintBackend);
90
100
  generate(cwd: string, schema: GenerateSchema, options?: GenerateOptions): Promise<GenerateResult>;
91
- validate(cwd: string, schema: ValidateSchema, options?: ValidateOptions): Promise<ValidateResult>;
101
+ validate<TSchema extends ValidateSchema>(cwd: string, schema: TSchema, options?: ValidateOptions): Promise<ValidateResult<TSchema>>;
92
102
  private patternToRegex;
93
103
  }
94
104
 
package/dist/index.d.ts CHANGED
@@ -44,6 +44,16 @@ interface LintBackend {
44
44
  exists(path: string): boolean;
45
45
  }
46
46
 
47
+ type MapValidateSchema<T> = {
48
+ [K in keyof T]: T[K] extends {
49
+ type: "file";
50
+ } ? ValidateFileResult : T[K] extends {
51
+ type: "directory";
52
+ children?: infer C;
53
+ } ? ValidateDirectoryResult & {
54
+ children: C extends object ? MapValidateSchema<C> : undefined;
55
+ } : never;
56
+ };
47
57
  interface GenerateOptions {
48
58
  overwrite?: boolean;
49
59
  recursive?: boolean;
@@ -64,9 +74,9 @@ interface ValidateDirectoryResult {
64
74
  }
65
75
  type ValidateNodeResult = ValidateFileResult | ValidateDirectoryResult;
66
76
  type ValidatePathResult = Record<string, ValidateNodeResult>;
67
- interface ValidateResult {
77
+ interface ValidateResult<TSchema> {
68
78
  cwd: string;
69
- paths: ValidatePathResult;
79
+ paths: MapValidateSchema<TSchema>;
70
80
  }
71
81
  interface GenerateFileResult {
72
82
  type: "file";
@@ -88,7 +98,7 @@ declare class DirectoryLint {
88
98
  private readonly backend;
89
99
  constructor(backend?: LintBackend);
90
100
  generate(cwd: string, schema: GenerateSchema, options?: GenerateOptions): Promise<GenerateResult>;
91
- validate(cwd: string, schema: ValidateSchema, options?: ValidateOptions): Promise<ValidateResult>;
101
+ validate<TSchema extends ValidateSchema>(cwd: string, schema: TSchema, options?: ValidateOptions): Promise<ValidateResult<TSchema>>;
92
102
  private patternToRegex;
93
103
  }
94
104
 
package/dist/index.js CHANGED
@@ -51,35 +51,48 @@ var DirectoryLint = class {
51
51
  cwd,
52
52
  paths: {}
53
53
  };
54
- if (!this.backend.exists(cwd)) this.backend.makeDirectory(cwd, options?.recursive);
54
+ if (!this.backend.exists(cwd)) {
55
+ this.backend.makeDirectory(cwd, options?.recursive);
56
+ }
55
57
  for (const [name, node] of Object.entries(schema)) {
56
58
  const isRegexLiteral = name.startsWith("/") && name.endsWith("/");
57
59
  if (isRegexLiteral) throw new RegexNotSupported(name);
58
60
  const fullPath = join(cwd, name);
59
61
  if (node.type === "directory") {
60
- let childrenResult = void 0;
62
+ let childrenResult;
61
63
  if (!this.backend.exists(fullPath)) {
62
64
  this.backend.makeDirectory(fullPath, options?.recursive);
63
65
  }
64
66
  if (node.children) {
65
- childrenResult = await this.generate(fullPath, node.children, options);
67
+ childrenResult = await this.generate(
68
+ fullPath,
69
+ node.children,
70
+ options
71
+ );
66
72
  }
67
73
  result.paths[name] = {
68
- type: node.type,
74
+ type: "directory",
69
75
  path: fullPath,
70
- ...childrenResult?.paths && { children: childrenResult.paths }
76
+ ...childrenResult?.paths && {
77
+ children: childrenResult.paths
78
+ }
71
79
  };
72
- } else if (node.type === "file") {
80
+ }
81
+ if (node.type === "file") {
73
82
  if (!this.backend.exists(fullPath)) {
74
- this.backend.writeFile(fullPath, node.content === void 0 ? "" : node.content);
75
- } else {
76
- if (options?.overwrite) {
77
- this.backend.writeFile(fullPath, node.content === void 0 ? "" : node.content);
78
- }
83
+ this.backend.writeFile(
84
+ fullPath,
85
+ node.content ?? ""
86
+ );
87
+ } else if (options?.overwrite) {
88
+ this.backend.writeFile(
89
+ fullPath,
90
+ node.content ?? ""
91
+ );
79
92
  }
80
93
  result.paths[name] = {
81
- path: fullPath,
82
- type: node.type
94
+ type: "file",
95
+ path: fullPath
83
96
  };
84
97
  }
85
98
  }
@@ -93,39 +106,54 @@ var DirectoryLint = class {
93
106
  const items = this.backend.getAllItems(cwd);
94
107
  const processedNames = /* @__PURE__ */ new Set();
95
108
  const sortedEntries = Object.entries(schema).sort(([a], [b]) => {
96
- const aHasWildcard = a.includes("*");
97
- const bHasWildcard = b.includes("*");
109
+ const aHasWildcard = String(a).includes("*");
110
+ const bHasWildcard = String(b).includes("*");
98
111
  if (!aHasWildcard && bHasWildcard) return -1;
99
112
  if (aHasWildcard && !bHasWildcard) return 1;
100
113
  return 0;
101
114
  });
102
115
  for (const [pattern, node] of sortedEntries) {
103
- const regex = this.patternToRegex(pattern);
116
+ const regex = this.patternToRegex(String(pattern));
104
117
  const matchedItems = items.filter(
105
118
  (item) => regex.test(item.name) && !processedNames.has(item.name)
106
119
  );
107
120
  const isRequired = node.required ?? true;
108
- if (matchedItems.length === 0 && isRequired) throw new InvalidStructure(pattern);
121
+ if (matchedItems.length === 0 && isRequired) {
122
+ throw new InvalidStructure(String(pattern));
123
+ }
109
124
  for (const { name, type } of matchedItems) {
110
125
  if (options?.ignore.includes(name)) continue;
111
126
  processedNames.add(name);
112
127
  const fullPath = join(cwd, name);
113
128
  if (node.type === "directory") {
114
- if (type !== "directory") throw new InvalidStructure(fullPath);
115
- let childrenResult = void 0;
129
+ if (type !== "directory") {
130
+ throw new InvalidStructure(fullPath);
131
+ }
132
+ let childrenResult;
116
133
  if (node.children) {
117
- childrenResult = await this.validate(fullPath, node.children, options);
134
+ childrenResult = await this.validate(
135
+ fullPath,
136
+ node.children,
137
+ options
138
+ );
118
139
  }
119
140
  result.paths[name] = {
120
141
  path: fullPath,
121
142
  name,
122
143
  type: "directory",
123
- ...childrenResult?.paths && { children: childrenResult.paths }
144
+ ...childrenResult?.paths && {
145
+ children: childrenResult.paths
146
+ }
124
147
  };
125
- } else if (node.type === "file") {
126
- if (type !== "file") throw new InvalidStructure(fullPath);
148
+ }
149
+ if (node.type === "file") {
150
+ if (type !== "file") {
151
+ throw new InvalidStructure(fullPath);
152
+ }
127
153
  const content = this.backend.readFile(fullPath);
128
- if (node.validate ? !node.validate(content) : false) throw new InvalidContent(fullPath);
154
+ if (node.validate && !node.validate(content)) {
155
+ throw new InvalidContent(fullPath);
156
+ }
129
157
  result.paths[name] = {
130
158
  path: fullPath,
131
159
  name,
package/package.json CHANGED
@@ -1,38 +1,38 @@
1
- {
2
- "name": "directory-lint",
3
- "version": "2.0.2",
4
- "description": "Directory Lint",
5
- "license": "MIT",
6
- "author": "Henry Vilani",
7
- "type": "module",
8
- "types": "./dist/index.d.ts",
9
- "main": "./dist/index.js",
10
- "exports": {
11
- ".": {
12
- "types": "./dist/index.d.ts",
13
- "import": "./dist/index.js",
14
- "require": "./dist/index.cjs"
15
- }
16
- },
17
- "files": [
18
- "dist"
19
- ],
20
- "scripts": {
21
- "build": "tsup src/index.ts --format cjs,esm --dts --clean",
22
- "example:basic": "ts-node examples/basic-generation.ts"
23
- },
24
- "keywords": [
25
- "linter",
26
- "validation",
27
- "filesystem",
28
- "directory-structure",
29
- "architecture",
30
- "lint"
31
- ],
32
- "devDependencies": {
33
- "@types/node": "^25.2.0",
34
- "ts-node": "^10.9.2",
35
- "tsup": "^8.5.1",
36
- "typescript": "^5.9.3"
37
- }
38
- }
1
+ {
2
+ "name": "directory-lint",
3
+ "version": "2.0.3",
4
+ "description": "Directory Lint",
5
+ "license": "MIT",
6
+ "author": "Henry Vilani",
7
+ "type": "module",
8
+ "types": "./dist/index.d.ts",
9
+ "main": "./dist/index.js",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "require": "./dist/index.cjs"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean",
22
+ "example:basic": "ts-node examples/basic-generation.ts"
23
+ },
24
+ "keywords": [
25
+ "linter",
26
+ "validation",
27
+ "filesystem",
28
+ "directory-structure",
29
+ "architecture",
30
+ "lint"
31
+ ],
32
+ "devDependencies": {
33
+ "@types/node": "^25.2.0",
34
+ "ts-node": "^10.9.2",
35
+ "tsup": "^8.5.1",
36
+ "typescript": "^5.9.3"
37
+ }
38
+ }