barrelize 1.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.
- package/LICENSE +21 -0
- package/README.md +132 -0
- package/bin/cli.js +5 -0
- package/lib/index.js +771 -0
- package/lib/src/cli/cli.d.ts +1 -0
- package/lib/src/cli/commands/generate-command-options.d.ts +3 -0
- package/lib/src/cli/commands/generate-command.d.ts +2 -0
- package/lib/src/cli/commands/init-command.d.ts +1 -0
- package/lib/src/config/config.d.ts +15 -0
- package/lib/src/config/output-config.d.ts +8 -0
- package/lib/src/config/parse-config.d.ts +2 -0
- package/lib/src/generate/generate-barrels.d.ts +2 -0
- package/lib/src/index.d.ts +11 -0
- package/lib/src/log/colorize.d.ts +12 -0
- package/lib/src/log/log-validation-error.d.ts +2 -0
- package/lib/src/log/log.d.ts +3 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Nizami
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Barrelize
|
|
2
|
+
|
|
3
|
+
🚀 A modern, lightweight and efficient tool for automatically generating index (barrel) files in your JavaScript and TypeScript projects.
|
|
4
|
+
|
|
5
|
+
Barrelize simplifies module exports by creating clean, centralized `index.js` or `index.ts` files, reducing boilerplate and improving project organization.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/barrelize)
|
|
8
|
+
|
|
9
|
+
[
|
|
10
|
+
](https://opensource.org/licenses/MIT)
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
- **Automatic Barrel Generation**: Scans directories and creates index files with exports for all modules.
|
|
14
|
+
- **TypeScript Support**: Seamlessly works with TypeScript projects, preserving type safety.
|
|
15
|
+
- **Customizable**: Configure file patterns, ignore specific files, or customize export styles (named, default, or both).
|
|
16
|
+
- **Recursive**: Optionally generate barrels for nested directories.
|
|
17
|
+
- **CLI & API**: Use via command line for quick setups or integrate programmatically in your build scripts.
|
|
18
|
+
|
|
19
|
+
### Why Use Barrelize?
|
|
20
|
+
- **Save Time**: Eliminate manual creation and maintenance of barrel files.
|
|
21
|
+
- **Cleaner Imports**: Simplify import statements with a single entry point for each directory.
|
|
22
|
+
- **Scalable**: Ideal for large projects with complex folder structures.
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install -D barrelize
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
1. Initialize configuration (optional):
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npx barrelize init
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
2. Generate barrel files:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx barrelize
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## CLI Commands
|
|
46
|
+
|
|
47
|
+
### `barrelize init [config path]`
|
|
48
|
+
|
|
49
|
+
Creates a `.barrelize` configuration file in your project.
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npx barrelize init # Creates .barrelize in current directory
|
|
53
|
+
npx barrelize init barrelize.json # Creates config at specified path
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### `barrelize [config path]`
|
|
57
|
+
|
|
58
|
+
Generates barrel (index) files based on your configuration.
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npx barrelize # Uses default .barrelize config
|
|
62
|
+
npx barrelize -c barrelize.json # Uses custom config file
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Configuration
|
|
66
|
+
|
|
67
|
+
Create a `.barrelize` file in your project root:
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"directories": [
|
|
72
|
+
{
|
|
73
|
+
"path": "src",
|
|
74
|
+
"include": ["**/*.ts", "**/*.tsx"],
|
|
75
|
+
"exclude": ["**/*.test.ts", "**/*.spec.ts"],
|
|
76
|
+
"order": ["types", "constants", "utils"],
|
|
77
|
+
"keepFileExtension": true,
|
|
78
|
+
"replace": [
|
|
79
|
+
{
|
|
80
|
+
"find": ".ts$",
|
|
81
|
+
"replacement": ""
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Example
|
|
90
|
+
|
|
91
|
+
Before:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
src/
|
|
95
|
+
├── types.ts
|
|
96
|
+
├── constants.ts
|
|
97
|
+
├── utils.ts
|
|
98
|
+
└── components/
|
|
99
|
+
├── Button.tsx
|
|
100
|
+
└── Input.tsx
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
After running `barrelize`:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
src/
|
|
107
|
+
├── types.ts
|
|
108
|
+
├── constants.ts
|
|
109
|
+
├── utils.ts
|
|
110
|
+
├── index.ts # New!
|
|
111
|
+
└── components/
|
|
112
|
+
├── Button.tsx
|
|
113
|
+
└── Input.tsx
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Generated `src/index.ts`:
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
export * from './types';
|
|
120
|
+
export * from './constants';
|
|
121
|
+
export * from './utils';
|
|
122
|
+
export * from './components/Button.tsx';
|
|
123
|
+
export * from './components/Input.tsx';
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Contributing
|
|
127
|
+
|
|
128
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
129
|
+
|
|
130
|
+
## License
|
|
131
|
+
|
|
132
|
+
MIT © Nizami
|
package/bin/cli.js
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,771 @@
|
|
|
1
|
+
import JSON5 from "json5";
|
|
2
|
+
import { writeFile, readFile } from "node:fs/promises";
|
|
3
|
+
import { glob } from "glob";
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
import { resolve, dirname, join } from "node:path";
|
|
6
|
+
import { cac } from "cac";
|
|
7
|
+
const name = "barrelize";
|
|
8
|
+
const version = "1.0.0";
|
|
9
|
+
function cliInit() {
|
|
10
|
+
const cli = cac(name);
|
|
11
|
+
cli.command("[config path]", `Generate 'index.ts' files for all directories`).action(async (config) => {
|
|
12
|
+
await runGenerateCommand({ configPath: config || ".barrelize" });
|
|
13
|
+
});
|
|
14
|
+
cli.command("init [config path]", "Create .barrelize config file if does not exist").example("barrelize init").example("barrelize init .barrelize").example("barrelize init root/.barrelize").action(async (path = ".barrelize") => {
|
|
15
|
+
await runInitCommand(path);
|
|
16
|
+
});
|
|
17
|
+
cli.help();
|
|
18
|
+
cli.version(version);
|
|
19
|
+
try {
|
|
20
|
+
cli.parse();
|
|
21
|
+
} catch (error) {
|
|
22
|
+
if (error instanceof Error) {
|
|
23
|
+
logError(error.message);
|
|
24
|
+
} else {
|
|
25
|
+
logError(String(error));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
var _accessExpressionAsString = {};
|
|
30
|
+
var hasRequired_accessExpressionAsString;
|
|
31
|
+
function require_accessExpressionAsString() {
|
|
32
|
+
if (hasRequired_accessExpressionAsString) return _accessExpressionAsString;
|
|
33
|
+
hasRequired_accessExpressionAsString = 1;
|
|
34
|
+
Object.defineProperty(_accessExpressionAsString, "__esModule", { value: true });
|
|
35
|
+
_accessExpressionAsString._accessExpressionAsString = void 0;
|
|
36
|
+
const _accessExpressionAsString$1 = (str) => variable(str) ? `.${str}` : `[${JSON.stringify(str)}]`;
|
|
37
|
+
_accessExpressionAsString._accessExpressionAsString = _accessExpressionAsString$1;
|
|
38
|
+
const variable = (str) => reserved(str) === false && /^[a-zA-Z_$][a-zA-Z_$0-9]*$/g.test(str);
|
|
39
|
+
const reserved = (str) => RESERVED.has(str);
|
|
40
|
+
const RESERVED = /* @__PURE__ */ new Set([
|
|
41
|
+
"break",
|
|
42
|
+
"case",
|
|
43
|
+
"catch",
|
|
44
|
+
"class",
|
|
45
|
+
"const",
|
|
46
|
+
"continue",
|
|
47
|
+
"debugger",
|
|
48
|
+
"default",
|
|
49
|
+
"delete",
|
|
50
|
+
"do",
|
|
51
|
+
"else",
|
|
52
|
+
"enum",
|
|
53
|
+
"export",
|
|
54
|
+
"extends",
|
|
55
|
+
"false",
|
|
56
|
+
"finally",
|
|
57
|
+
"for",
|
|
58
|
+
"function",
|
|
59
|
+
"if",
|
|
60
|
+
"import",
|
|
61
|
+
"in",
|
|
62
|
+
"instanceof",
|
|
63
|
+
"new",
|
|
64
|
+
"null",
|
|
65
|
+
"return",
|
|
66
|
+
"super",
|
|
67
|
+
"switch",
|
|
68
|
+
"this",
|
|
69
|
+
"throw",
|
|
70
|
+
"true",
|
|
71
|
+
"try",
|
|
72
|
+
"typeof",
|
|
73
|
+
"var",
|
|
74
|
+
"void",
|
|
75
|
+
"while",
|
|
76
|
+
"with"
|
|
77
|
+
]);
|
|
78
|
+
return _accessExpressionAsString;
|
|
79
|
+
}
|
|
80
|
+
var _accessExpressionAsStringExports = /* @__PURE__ */ require_accessExpressionAsString();
|
|
81
|
+
var _validateReport = {};
|
|
82
|
+
var hasRequired_validateReport;
|
|
83
|
+
function require_validateReport() {
|
|
84
|
+
if (hasRequired_validateReport) return _validateReport;
|
|
85
|
+
hasRequired_validateReport = 1;
|
|
86
|
+
Object.defineProperty(_validateReport, "__esModule", { value: true });
|
|
87
|
+
_validateReport._validateReport = void 0;
|
|
88
|
+
const _validateReport$1 = (array) => {
|
|
89
|
+
const reportable = (path) => {
|
|
90
|
+
if (array.length === 0)
|
|
91
|
+
return true;
|
|
92
|
+
const last = array[array.length - 1].path;
|
|
93
|
+
return path.length > last.length || last.substring(0, path.length) !== path;
|
|
94
|
+
};
|
|
95
|
+
return (exceptable, error) => {
|
|
96
|
+
if (exceptable && reportable(error.path))
|
|
97
|
+
array.push(error);
|
|
98
|
+
return false;
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
_validateReport._validateReport = _validateReport$1;
|
|
102
|
+
return _validateReport;
|
|
103
|
+
}
|
|
104
|
+
var _validateReportExports = /* @__PURE__ */ require_validateReport();
|
|
105
|
+
var _createStandardSchema = {};
|
|
106
|
+
var hasRequired_createStandardSchema;
|
|
107
|
+
function require_createStandardSchema() {
|
|
108
|
+
if (hasRequired_createStandardSchema) return _createStandardSchema;
|
|
109
|
+
hasRequired_createStandardSchema = 1;
|
|
110
|
+
Object.defineProperty(_createStandardSchema, "__esModule", { value: true });
|
|
111
|
+
_createStandardSchema._createStandardSchema = void 0;
|
|
112
|
+
const _createStandardSchema$1 = (fn) => Object.assign(fn, {
|
|
113
|
+
"~standard": {
|
|
114
|
+
version: 1,
|
|
115
|
+
vendor: "typia",
|
|
116
|
+
validate: (input) => {
|
|
117
|
+
const result = fn(input);
|
|
118
|
+
if (result.success) {
|
|
119
|
+
return {
|
|
120
|
+
value: result.data
|
|
121
|
+
};
|
|
122
|
+
} else {
|
|
123
|
+
return {
|
|
124
|
+
issues: result.errors.map((error) => ({
|
|
125
|
+
message: `expected ${error.expected}, got ${error.value}`,
|
|
126
|
+
path: typiaPathToStandardSchemaPath(error.path)
|
|
127
|
+
}))
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
_createStandardSchema._createStandardSchema = _createStandardSchema$1;
|
|
134
|
+
var PathParserState;
|
|
135
|
+
(function(PathParserState2) {
|
|
136
|
+
PathParserState2[PathParserState2["Start"] = 0] = "Start";
|
|
137
|
+
PathParserState2[PathParserState2["Property"] = 1] = "Property";
|
|
138
|
+
PathParserState2[PathParserState2["StringKey"] = 2] = "StringKey";
|
|
139
|
+
PathParserState2[PathParserState2["NumberKey"] = 3] = "NumberKey";
|
|
140
|
+
})(PathParserState || (PathParserState = {}));
|
|
141
|
+
const typiaPathToStandardSchemaPath = (path) => {
|
|
142
|
+
if (!path.startsWith("$input")) {
|
|
143
|
+
throw new Error(`Invalid path: ${JSON.stringify(path)}`);
|
|
144
|
+
}
|
|
145
|
+
const segments = [];
|
|
146
|
+
let currentSegment = "";
|
|
147
|
+
let state = PathParserState.Start;
|
|
148
|
+
let index = "$input".length - 1;
|
|
149
|
+
while (index < path.length - 1) {
|
|
150
|
+
index++;
|
|
151
|
+
const char = path[index];
|
|
152
|
+
if (state === PathParserState.Property) {
|
|
153
|
+
if (char === "." || char === "[") {
|
|
154
|
+
segments.push({
|
|
155
|
+
key: currentSegment
|
|
156
|
+
});
|
|
157
|
+
state = PathParserState.Start;
|
|
158
|
+
} else if (index === path.length - 1) {
|
|
159
|
+
currentSegment += char;
|
|
160
|
+
segments.push({
|
|
161
|
+
key: currentSegment
|
|
162
|
+
});
|
|
163
|
+
index++;
|
|
164
|
+
state = PathParserState.Start;
|
|
165
|
+
} else {
|
|
166
|
+
currentSegment += char;
|
|
167
|
+
}
|
|
168
|
+
} else if (state === PathParserState.StringKey) {
|
|
169
|
+
if (char === '"') {
|
|
170
|
+
segments.push({
|
|
171
|
+
key: JSON.parse(currentSegment + char)
|
|
172
|
+
});
|
|
173
|
+
index += 2;
|
|
174
|
+
state = PathParserState.Start;
|
|
175
|
+
} else if (char === "\\") {
|
|
176
|
+
currentSegment += path[index];
|
|
177
|
+
index++;
|
|
178
|
+
currentSegment += path[index];
|
|
179
|
+
} else {
|
|
180
|
+
currentSegment += char;
|
|
181
|
+
}
|
|
182
|
+
} else if (state === PathParserState.NumberKey) {
|
|
183
|
+
if (char === "]") {
|
|
184
|
+
segments.push({
|
|
185
|
+
key: Number.parseInt(currentSegment)
|
|
186
|
+
});
|
|
187
|
+
index++;
|
|
188
|
+
state = PathParserState.Start;
|
|
189
|
+
} else {
|
|
190
|
+
currentSegment += char;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (state === PathParserState.Start && index < path.length - 1) {
|
|
194
|
+
const newChar = path[index];
|
|
195
|
+
currentSegment = "";
|
|
196
|
+
if (newChar === "[") {
|
|
197
|
+
if (path[index + 1] === '"') {
|
|
198
|
+
state = PathParserState.StringKey;
|
|
199
|
+
index++;
|
|
200
|
+
currentSegment = '"';
|
|
201
|
+
} else {
|
|
202
|
+
state = PathParserState.NumberKey;
|
|
203
|
+
}
|
|
204
|
+
} else if (newChar === ".") {
|
|
205
|
+
state = PathParserState.Property;
|
|
206
|
+
} else {
|
|
207
|
+
throw new Error("Unreachable: pointer points invalid character");
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (state !== PathParserState.Start) {
|
|
212
|
+
throw new Error(`Failed to parse path: ${JSON.stringify(path)}`);
|
|
213
|
+
}
|
|
214
|
+
return segments;
|
|
215
|
+
};
|
|
216
|
+
return _createStandardSchema;
|
|
217
|
+
}
|
|
218
|
+
var _createStandardSchemaExports = /* @__PURE__ */ require_createStandardSchema();
|
|
219
|
+
const validateGenerateOptions = (() => {
|
|
220
|
+
const _io0 = (input, _exceptionable = true) => "string" === typeof input.configPath && (1 === Object.keys(input).length || Object.keys(input).every((key) => {
|
|
221
|
+
if (["configPath"].some((prop) => key === prop))
|
|
222
|
+
return true;
|
|
223
|
+
const value = input[key];
|
|
224
|
+
if (void 0 === value)
|
|
225
|
+
return true;
|
|
226
|
+
return false;
|
|
227
|
+
}));
|
|
228
|
+
const _vo0 = (input, _path, _exceptionable = true) => ["string" === typeof input.configPath || _report(_exceptionable, {
|
|
229
|
+
path: _path + ".configPath",
|
|
230
|
+
expected: "string",
|
|
231
|
+
value: input.configPath
|
|
232
|
+
}), 1 === Object.keys(input).length || (false === _exceptionable || Object.keys(input).map((key) => {
|
|
233
|
+
if (["configPath"].some((prop) => key === prop))
|
|
234
|
+
return true;
|
|
235
|
+
const value = input[key];
|
|
236
|
+
if (void 0 === value)
|
|
237
|
+
return true;
|
|
238
|
+
return _report(_exceptionable, {
|
|
239
|
+
path: _path + _accessExpressionAsStringExports._accessExpressionAsString(key),
|
|
240
|
+
expected: "undefined",
|
|
241
|
+
value
|
|
242
|
+
});
|
|
243
|
+
}).every((flag) => flag))].every((flag) => flag);
|
|
244
|
+
const __is = (input, _exceptionable = true) => "object" === typeof input && null !== input && _io0(input, true);
|
|
245
|
+
let errors;
|
|
246
|
+
let _report;
|
|
247
|
+
return _createStandardSchemaExports._createStandardSchema((input) => {
|
|
248
|
+
if (false === __is(input)) {
|
|
249
|
+
errors = [];
|
|
250
|
+
_report = _validateReportExports._validateReport(errors);
|
|
251
|
+
((input2, _path, _exceptionable = true) => ("object" === typeof input2 && null !== input2 || _report(true, {
|
|
252
|
+
path: _path + "",
|
|
253
|
+
expected: "GenerateCommandOptions",
|
|
254
|
+
value: input2
|
|
255
|
+
})) && _vo0(input2, _path + "", true) || _report(true, {
|
|
256
|
+
path: _path + "",
|
|
257
|
+
expected: "GenerateCommandOptions",
|
|
258
|
+
value: input2
|
|
259
|
+
}))(input, "$input", true);
|
|
260
|
+
const success = 0 === errors.length;
|
|
261
|
+
return success ? {
|
|
262
|
+
success,
|
|
263
|
+
data: input
|
|
264
|
+
} : {
|
|
265
|
+
success,
|
|
266
|
+
errors,
|
|
267
|
+
data: input
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
return {
|
|
271
|
+
success: true,
|
|
272
|
+
data: input
|
|
273
|
+
};
|
|
274
|
+
});
|
|
275
|
+
})();
|
|
276
|
+
async function runGenerateCommand(options) {
|
|
277
|
+
const validatedOptions = validateGenerateOptions(options);
|
|
278
|
+
if (!validatedOptions.success) {
|
|
279
|
+
logValidationError(`Invalid 'generate' command options`, validatedOptions);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
if (!existsSync(options.configPath)) {
|
|
283
|
+
logError(`Couldn't find barrelize config file with path '${options.configPath}'`);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
const config = await parseConfig(options.configPath);
|
|
287
|
+
const validatedConfig = validateConfig(config);
|
|
288
|
+
if (!validatedConfig.success) {
|
|
289
|
+
logValidationError(`Invalid barrelize config`, validatedConfig);
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
const rootPath = resolve(dirname(options.configPath));
|
|
293
|
+
await generateBarrels(rootPath, validatedConfig.data);
|
|
294
|
+
}
|
|
295
|
+
const configTemplate = {
|
|
296
|
+
directories: [
|
|
297
|
+
{
|
|
298
|
+
path: "src",
|
|
299
|
+
include: ["**/*.ts"],
|
|
300
|
+
exclude: ["**/*.test.ts"],
|
|
301
|
+
order: ["models", "api"],
|
|
302
|
+
indexFilePath: "index.ts"
|
|
303
|
+
}
|
|
304
|
+
]
|
|
305
|
+
};
|
|
306
|
+
async function runInitCommand(baseConfigFilePath) {
|
|
307
|
+
const configFilePath = resolve(process.cwd(), baseConfigFilePath);
|
|
308
|
+
if (existsSync(configFilePath)) {
|
|
309
|
+
logWarning(`Config file '${configFilePath}' already exists`);
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
const configDirectoryPath = dirname(configFilePath);
|
|
313
|
+
if (!existsSync(configDirectoryPath)) {
|
|
314
|
+
logWarning(`Directory '${configDirectoryPath}' does not exist`);
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
const configTemplateJson = JSON.stringify(configTemplate, null, 2);
|
|
318
|
+
await writeFile(configFilePath, configTemplateJson);
|
|
319
|
+
console.log(colorize(baseConfigFilePath, TerminalColor.CYAN), colorize(`file created`, TerminalColor.GRAY));
|
|
320
|
+
console.log(colorize(configTemplateJson, TerminalColor.GREEN));
|
|
321
|
+
}
|
|
322
|
+
const validateConfig = (() => {
|
|
323
|
+
const _io0 = (input, _exceptionable = true) => Array.isArray(input.directories) && input.directories.every((elem, _index1) => "object" === typeof elem && null !== elem && _io1(elem, _exceptionable)) && (1 === Object.keys(input).length || Object.keys(input).every((key) => {
|
|
324
|
+
if (["directories"].some((prop) => key === prop))
|
|
325
|
+
return true;
|
|
326
|
+
const value = input[key];
|
|
327
|
+
if (void 0 === value)
|
|
328
|
+
return true;
|
|
329
|
+
return false;
|
|
330
|
+
}));
|
|
331
|
+
const _io1 = (input, _exceptionable = true) => "string" === typeof input.path && (Array.isArray(input.include) && input.include.every((elem, _index2) => "string" === typeof elem)) && (Array.isArray(input.exclude) && input.exclude.every((elem, _index3) => "string" === typeof elem)) && (void 0 === input.order || Array.isArray(input.order) && input.order.every((elem, _index4) => "string" === typeof elem)) && (void 0 === input.indexFilePath || "string" === typeof input.indexFilePath) && (void 0 === input.keepFileExtension || "boolean" === typeof input.keepFileExtension) && (void 0 === input.replace || Array.isArray(input.replace) && input.replace.every((elem, _index5) => "object" === typeof elem && null !== elem && _io2(elem, _exceptionable))) && (3 === Object.keys(input).length || Object.keys(input).every((key) => {
|
|
332
|
+
if (["path", "include", "exclude", "order", "indexFilePath", "keepFileExtension", "replace"].some((prop) => key === prop))
|
|
333
|
+
return true;
|
|
334
|
+
const value = input[key];
|
|
335
|
+
if (void 0 === value)
|
|
336
|
+
return true;
|
|
337
|
+
return false;
|
|
338
|
+
}));
|
|
339
|
+
const _io2 = (input, _exceptionable = true) => "string" === typeof input.find && "string" === typeof input.replacement && (2 === Object.keys(input).length || Object.keys(input).every((key) => {
|
|
340
|
+
if (["find", "replacement"].some((prop) => key === prop))
|
|
341
|
+
return true;
|
|
342
|
+
const value = input[key];
|
|
343
|
+
if (void 0 === value)
|
|
344
|
+
return true;
|
|
345
|
+
return false;
|
|
346
|
+
}));
|
|
347
|
+
const _vo0 = (input, _path, _exceptionable = true) => [(Array.isArray(input.directories) || _report(_exceptionable, {
|
|
348
|
+
path: _path + ".directories",
|
|
349
|
+
expected: "Array<__type>",
|
|
350
|
+
value: input.directories
|
|
351
|
+
})) && input.directories.map((elem, _index6) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
352
|
+
path: _path + ".directories[" + _index6 + "]",
|
|
353
|
+
expected: "__type",
|
|
354
|
+
value: elem
|
|
355
|
+
})) && _vo1(elem, _path + ".directories[" + _index6 + "]", _exceptionable) || _report(_exceptionable, {
|
|
356
|
+
path: _path + ".directories[" + _index6 + "]",
|
|
357
|
+
expected: "__type",
|
|
358
|
+
value: elem
|
|
359
|
+
})).every((flag) => flag) || _report(_exceptionable, {
|
|
360
|
+
path: _path + ".directories",
|
|
361
|
+
expected: "Array<__type>",
|
|
362
|
+
value: input.directories
|
|
363
|
+
}), 1 === Object.keys(input).length || (false === _exceptionable || Object.keys(input).map((key) => {
|
|
364
|
+
if (["directories"].some((prop) => key === prop))
|
|
365
|
+
return true;
|
|
366
|
+
const value = input[key];
|
|
367
|
+
if (void 0 === value)
|
|
368
|
+
return true;
|
|
369
|
+
return _report(_exceptionable, {
|
|
370
|
+
path: _path + _accessExpressionAsStringExports._accessExpressionAsString(key),
|
|
371
|
+
expected: "undefined",
|
|
372
|
+
value
|
|
373
|
+
});
|
|
374
|
+
}).every((flag) => flag))].every((flag) => flag);
|
|
375
|
+
const _vo1 = (input, _path, _exceptionable = true) => ["string" === typeof input.path || _report(_exceptionable, {
|
|
376
|
+
path: _path + ".path",
|
|
377
|
+
expected: "string",
|
|
378
|
+
value: input.path
|
|
379
|
+
}), (Array.isArray(input.include) || _report(_exceptionable, {
|
|
380
|
+
path: _path + ".include",
|
|
381
|
+
expected: "Array<string>",
|
|
382
|
+
value: input.include
|
|
383
|
+
})) && input.include.map((elem, _index7) => "string" === typeof elem || _report(_exceptionable, {
|
|
384
|
+
path: _path + ".include[" + _index7 + "]",
|
|
385
|
+
expected: "string",
|
|
386
|
+
value: elem
|
|
387
|
+
})).every((flag) => flag) || _report(_exceptionable, {
|
|
388
|
+
path: _path + ".include",
|
|
389
|
+
expected: "Array<string>",
|
|
390
|
+
value: input.include
|
|
391
|
+
}), (Array.isArray(input.exclude) || _report(_exceptionable, {
|
|
392
|
+
path: _path + ".exclude",
|
|
393
|
+
expected: "Array<string>",
|
|
394
|
+
value: input.exclude
|
|
395
|
+
})) && input.exclude.map((elem, _index8) => "string" === typeof elem || _report(_exceptionable, {
|
|
396
|
+
path: _path + ".exclude[" + _index8 + "]",
|
|
397
|
+
expected: "string",
|
|
398
|
+
value: elem
|
|
399
|
+
})).every((flag) => flag) || _report(_exceptionable, {
|
|
400
|
+
path: _path + ".exclude",
|
|
401
|
+
expected: "Array<string>",
|
|
402
|
+
value: input.exclude
|
|
403
|
+
}), void 0 === input.order || (Array.isArray(input.order) || _report(_exceptionable, {
|
|
404
|
+
path: _path + ".order",
|
|
405
|
+
expected: "(Array<string> | undefined)",
|
|
406
|
+
value: input.order
|
|
407
|
+
})) && input.order.map((elem, _index9) => "string" === typeof elem || _report(_exceptionable, {
|
|
408
|
+
path: _path + ".order[" + _index9 + "]",
|
|
409
|
+
expected: "string",
|
|
410
|
+
value: elem
|
|
411
|
+
})).every((flag) => flag) || _report(_exceptionable, {
|
|
412
|
+
path: _path + ".order",
|
|
413
|
+
expected: "(Array<string> | undefined)",
|
|
414
|
+
value: input.order
|
|
415
|
+
}), void 0 === input.indexFilePath || "string" === typeof input.indexFilePath || _report(_exceptionable, {
|
|
416
|
+
path: _path + ".indexFilePath",
|
|
417
|
+
expected: "(string | undefined)",
|
|
418
|
+
value: input.indexFilePath
|
|
419
|
+
}), void 0 === input.keepFileExtension || "boolean" === typeof input.keepFileExtension || _report(_exceptionable, {
|
|
420
|
+
path: _path + ".keepFileExtension",
|
|
421
|
+
expected: "(boolean | undefined)",
|
|
422
|
+
value: input.keepFileExtension
|
|
423
|
+
}), void 0 === input.replace || (Array.isArray(input.replace) || _report(_exceptionable, {
|
|
424
|
+
path: _path + ".replace",
|
|
425
|
+
expected: "(Array<__type>.o1 | undefined)",
|
|
426
|
+
value: input.replace
|
|
427
|
+
})) && input.replace.map((elem, _index10) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
428
|
+
path: _path + ".replace[" + _index10 + "]",
|
|
429
|
+
expected: "__type.o1",
|
|
430
|
+
value: elem
|
|
431
|
+
})) && _vo2(elem, _path + ".replace[" + _index10 + "]", _exceptionable) || _report(_exceptionable, {
|
|
432
|
+
path: _path + ".replace[" + _index10 + "]",
|
|
433
|
+
expected: "__type.o1",
|
|
434
|
+
value: elem
|
|
435
|
+
})).every((flag) => flag) || _report(_exceptionable, {
|
|
436
|
+
path: _path + ".replace",
|
|
437
|
+
expected: "(Array<__type>.o1 | undefined)",
|
|
438
|
+
value: input.replace
|
|
439
|
+
}), 3 === Object.keys(input).length || (false === _exceptionable || Object.keys(input).map((key) => {
|
|
440
|
+
if (["path", "include", "exclude", "order", "indexFilePath", "keepFileExtension", "replace"].some((prop) => key === prop))
|
|
441
|
+
return true;
|
|
442
|
+
const value = input[key];
|
|
443
|
+
if (void 0 === value)
|
|
444
|
+
return true;
|
|
445
|
+
return _report(_exceptionable, {
|
|
446
|
+
path: _path + _accessExpressionAsStringExports._accessExpressionAsString(key),
|
|
447
|
+
expected: "undefined",
|
|
448
|
+
value
|
|
449
|
+
});
|
|
450
|
+
}).every((flag) => flag))].every((flag) => flag);
|
|
451
|
+
const _vo2 = (input, _path, _exceptionable = true) => ["string" === typeof input.find || _report(_exceptionable, {
|
|
452
|
+
path: _path + ".find",
|
|
453
|
+
expected: "string",
|
|
454
|
+
value: input.find
|
|
455
|
+
}), "string" === typeof input.replacement || _report(_exceptionable, {
|
|
456
|
+
path: _path + ".replacement",
|
|
457
|
+
expected: "string",
|
|
458
|
+
value: input.replacement
|
|
459
|
+
}), 2 === Object.keys(input).length || (false === _exceptionable || Object.keys(input).map((key) => {
|
|
460
|
+
if (["find", "replacement"].some((prop) => key === prop))
|
|
461
|
+
return true;
|
|
462
|
+
const value = input[key];
|
|
463
|
+
if (void 0 === value)
|
|
464
|
+
return true;
|
|
465
|
+
return _report(_exceptionable, {
|
|
466
|
+
path: _path + _accessExpressionAsStringExports._accessExpressionAsString(key),
|
|
467
|
+
expected: "undefined",
|
|
468
|
+
value
|
|
469
|
+
});
|
|
470
|
+
}).every((flag) => flag))].every((flag) => flag);
|
|
471
|
+
const __is = (input, _exceptionable = true) => "object" === typeof input && null !== input && _io0(input, true);
|
|
472
|
+
let errors;
|
|
473
|
+
let _report;
|
|
474
|
+
return _createStandardSchemaExports._createStandardSchema((input) => {
|
|
475
|
+
if (false === __is(input)) {
|
|
476
|
+
errors = [];
|
|
477
|
+
_report = _validateReportExports._validateReport(errors);
|
|
478
|
+
((input2, _path, _exceptionable = true) => ("object" === typeof input2 && null !== input2 || _report(true, {
|
|
479
|
+
path: _path + "",
|
|
480
|
+
expected: "Config",
|
|
481
|
+
value: input2
|
|
482
|
+
})) && _vo0(input2, _path + "", true) || _report(true, {
|
|
483
|
+
path: _path + "",
|
|
484
|
+
expected: "Config",
|
|
485
|
+
value: input2
|
|
486
|
+
}))(input, "$input", true);
|
|
487
|
+
const success = 0 === errors.length;
|
|
488
|
+
return success ? {
|
|
489
|
+
success,
|
|
490
|
+
data: input
|
|
491
|
+
} : {
|
|
492
|
+
success,
|
|
493
|
+
errors,
|
|
494
|
+
data: input
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
return {
|
|
498
|
+
success: true,
|
|
499
|
+
data: input
|
|
500
|
+
};
|
|
501
|
+
});
|
|
502
|
+
})();
|
|
503
|
+
const validateOutputConfig = (() => {
|
|
504
|
+
const _io0 = (input, _exceptionable = true) => "string" === typeof input.cwd && (Array.isArray(input.directories) && input.directories.every((elem, _index1) => "object" === typeof elem && null !== elem && _io1(elem, _exceptionable))) && (2 === Object.keys(input).length || Object.keys(input).every((key) => {
|
|
505
|
+
if (["cwd", "directories"].some((prop) => key === prop))
|
|
506
|
+
return true;
|
|
507
|
+
const value = input[key];
|
|
508
|
+
if (void 0 === value)
|
|
509
|
+
return true;
|
|
510
|
+
return false;
|
|
511
|
+
}));
|
|
512
|
+
const _io1 = (input, _exceptionable = true) => Array.isArray(input.files) && input.files.every((elem, _index2) => "string" === typeof elem) && (void 0 === input.order || Array.isArray(input.order) && input.order.every((elem, _index3) => "string" === typeof elem)) && (1 === Object.keys(input).length || Object.keys(input).every((key) => {
|
|
513
|
+
if (["files", "order"].some((prop) => key === prop))
|
|
514
|
+
return true;
|
|
515
|
+
const value = input[key];
|
|
516
|
+
if (void 0 === value)
|
|
517
|
+
return true;
|
|
518
|
+
return false;
|
|
519
|
+
}));
|
|
520
|
+
const _vo0 = (input, _path, _exceptionable = true) => ["string" === typeof input.cwd || _report(_exceptionable, {
|
|
521
|
+
path: _path + ".cwd",
|
|
522
|
+
expected: "string",
|
|
523
|
+
value: input.cwd
|
|
524
|
+
}), (Array.isArray(input.directories) || _report(_exceptionable, {
|
|
525
|
+
path: _path + ".directories",
|
|
526
|
+
expected: "Array<__type>",
|
|
527
|
+
value: input.directories
|
|
528
|
+
})) && input.directories.map((elem, _index4) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
|
|
529
|
+
path: _path + ".directories[" + _index4 + "]",
|
|
530
|
+
expected: "__type",
|
|
531
|
+
value: elem
|
|
532
|
+
})) && _vo1(elem, _path + ".directories[" + _index4 + "]", _exceptionable) || _report(_exceptionable, {
|
|
533
|
+
path: _path + ".directories[" + _index4 + "]",
|
|
534
|
+
expected: "__type",
|
|
535
|
+
value: elem
|
|
536
|
+
})).every((flag) => flag) || _report(_exceptionable, {
|
|
537
|
+
path: _path + ".directories",
|
|
538
|
+
expected: "Array<__type>",
|
|
539
|
+
value: input.directories
|
|
540
|
+
}), 2 === Object.keys(input).length || (false === _exceptionable || Object.keys(input).map((key) => {
|
|
541
|
+
if (["cwd", "directories"].some((prop) => key === prop))
|
|
542
|
+
return true;
|
|
543
|
+
const value = input[key];
|
|
544
|
+
if (void 0 === value)
|
|
545
|
+
return true;
|
|
546
|
+
return _report(_exceptionable, {
|
|
547
|
+
path: _path + _accessExpressionAsStringExports._accessExpressionAsString(key),
|
|
548
|
+
expected: "undefined",
|
|
549
|
+
value
|
|
550
|
+
});
|
|
551
|
+
}).every((flag) => flag))].every((flag) => flag);
|
|
552
|
+
const _vo1 = (input, _path, _exceptionable = true) => [(Array.isArray(input.files) || _report(_exceptionable, {
|
|
553
|
+
path: _path + ".files",
|
|
554
|
+
expected: "Array<string>",
|
|
555
|
+
value: input.files
|
|
556
|
+
})) && input.files.map((elem, _index5) => "string" === typeof elem || _report(_exceptionable, {
|
|
557
|
+
path: _path + ".files[" + _index5 + "]",
|
|
558
|
+
expected: "string",
|
|
559
|
+
value: elem
|
|
560
|
+
})).every((flag) => flag) || _report(_exceptionable, {
|
|
561
|
+
path: _path + ".files",
|
|
562
|
+
expected: "Array<string>",
|
|
563
|
+
value: input.files
|
|
564
|
+
}), void 0 === input.order || (Array.isArray(input.order) || _report(_exceptionable, {
|
|
565
|
+
path: _path + ".order",
|
|
566
|
+
expected: "(Array<string> | undefined)",
|
|
567
|
+
value: input.order
|
|
568
|
+
})) && input.order.map((elem, _index6) => "string" === typeof elem || _report(_exceptionable, {
|
|
569
|
+
path: _path + ".order[" + _index6 + "]",
|
|
570
|
+
expected: "string",
|
|
571
|
+
value: elem
|
|
572
|
+
})).every((flag) => flag) || _report(_exceptionable, {
|
|
573
|
+
path: _path + ".order",
|
|
574
|
+
expected: "(Array<string> | undefined)",
|
|
575
|
+
value: input.order
|
|
576
|
+
}), 1 === Object.keys(input).length || (false === _exceptionable || Object.keys(input).map((key) => {
|
|
577
|
+
if (["files", "order"].some((prop) => key === prop))
|
|
578
|
+
return true;
|
|
579
|
+
const value = input[key];
|
|
580
|
+
if (void 0 === value)
|
|
581
|
+
return true;
|
|
582
|
+
return _report(_exceptionable, {
|
|
583
|
+
path: _path + _accessExpressionAsStringExports._accessExpressionAsString(key),
|
|
584
|
+
expected: "undefined",
|
|
585
|
+
value
|
|
586
|
+
});
|
|
587
|
+
}).every((flag) => flag))].every((flag) => flag);
|
|
588
|
+
const __is = (input, _exceptionable = true) => "object" === typeof input && null !== input && _io0(input, true);
|
|
589
|
+
let errors;
|
|
590
|
+
let _report;
|
|
591
|
+
return _createStandardSchemaExports._createStandardSchema((input) => {
|
|
592
|
+
if (false === __is(input)) {
|
|
593
|
+
errors = [];
|
|
594
|
+
_report = _validateReportExports._validateReport(errors);
|
|
595
|
+
((input2, _path, _exceptionable = true) => ("object" === typeof input2 && null !== input2 || _report(true, {
|
|
596
|
+
path: _path + "",
|
|
597
|
+
expected: "OutputConfig",
|
|
598
|
+
value: input2
|
|
599
|
+
})) && _vo0(input2, _path + "", true) || _report(true, {
|
|
600
|
+
path: _path + "",
|
|
601
|
+
expected: "OutputConfig",
|
|
602
|
+
value: input2
|
|
603
|
+
}))(input, "$input", true);
|
|
604
|
+
const success = 0 === errors.length;
|
|
605
|
+
return success ? {
|
|
606
|
+
success,
|
|
607
|
+
data: input
|
|
608
|
+
} : {
|
|
609
|
+
success,
|
|
610
|
+
errors,
|
|
611
|
+
data: input
|
|
612
|
+
};
|
|
613
|
+
}
|
|
614
|
+
return {
|
|
615
|
+
success: true,
|
|
616
|
+
data: input
|
|
617
|
+
};
|
|
618
|
+
});
|
|
619
|
+
})();
|
|
620
|
+
async function parseConfig(configPath) {
|
|
621
|
+
const configJson = (await readFile(configPath)).toString();
|
|
622
|
+
try {
|
|
623
|
+
return JSON5.parse(configJson);
|
|
624
|
+
} catch (error) {
|
|
625
|
+
if (error instanceof SyntaxError) {
|
|
626
|
+
const referenceMatches = error.message.match(/at (\d+:\d+)/);
|
|
627
|
+
const reasonMatches = error.message.match(/(?<=JSON5: ).*?(?= at \d+:\d+)/);
|
|
628
|
+
if (referenceMatches && reasonMatches) {
|
|
629
|
+
const reference = `${configPath}:${referenceMatches[1]}`;
|
|
630
|
+
const reason = reasonMatches[0];
|
|
631
|
+
logError(`Barrelize json config syntax error: ${reason} at ${reference}:`);
|
|
632
|
+
return null;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
console.error(error);
|
|
636
|
+
return null;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
const DEFAULT_INDEX_FILE_PATH = "index.ts";
|
|
640
|
+
async function generateBarrels(rootPath, config) {
|
|
641
|
+
for (const directoryConfig of config.directories) {
|
|
642
|
+
const indexFileBasePath = directoryConfig.indexFilePath ?? DEFAULT_INDEX_FILE_PATH;
|
|
643
|
+
const indexFileRelativePath = join(directoryConfig.path, indexFileBasePath);
|
|
644
|
+
const indexFileAbsolutePath = resolve(rootPath, indexFileRelativePath);
|
|
645
|
+
const indexDirectory = dirname(indexFileAbsolutePath);
|
|
646
|
+
if (!existsSync(indexDirectory)) {
|
|
647
|
+
console.error(logWarning(`Index directory '${indexDirectory}' does not exist - skipping`));
|
|
648
|
+
console.error(logWarning(` Please verify the directory path in your configuration`));
|
|
649
|
+
continue;
|
|
650
|
+
}
|
|
651
|
+
const files = await generateBarrel(rootPath, directoryConfig);
|
|
652
|
+
const content = files.map((x) => `export * from './${x}';`).join("\n");
|
|
653
|
+
await writeFile(indexFileAbsolutePath, content);
|
|
654
|
+
console.log(
|
|
655
|
+
colorize(indexFileRelativePath, TerminalColor.CYAN),
|
|
656
|
+
colorize(`exports ${files.length} file${files.length > 1 ? "s" : ""}`, TerminalColor.GRAY)
|
|
657
|
+
);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
async function generateBarrel(rootPath, directoryConfig) {
|
|
661
|
+
const ignore = [...directoryConfig.exclude, "**/index.ts", "**/index.js"];
|
|
662
|
+
const cwd = resolve(rootPath, directoryConfig.path);
|
|
663
|
+
let files = await glob(directoryConfig.include, { cwd, ignore, nodir: true, includeChildMatches: true });
|
|
664
|
+
files = files.map((file) => file.replace(/\\/g, "/"));
|
|
665
|
+
files = handleFileExtension(directoryConfig, files);
|
|
666
|
+
files = handleOrder(directoryConfig, files);
|
|
667
|
+
files = handlePathReplacement(directoryConfig, files);
|
|
668
|
+
return files;
|
|
669
|
+
}
|
|
670
|
+
function handleFileExtension(config, files) {
|
|
671
|
+
if (!config.keepFileExtension) {
|
|
672
|
+
return files.map((file) => file.replace(/\.ts$/, ""));
|
|
673
|
+
}
|
|
674
|
+
return files;
|
|
675
|
+
}
|
|
676
|
+
function handlePathReplacement(config, files) {
|
|
677
|
+
if (!config.replace?.length) {
|
|
678
|
+
return files;
|
|
679
|
+
}
|
|
680
|
+
for (let i = 0; i < config.replace.length; i++) {
|
|
681
|
+
const { find, replacement } = config.replace[i];
|
|
682
|
+
try {
|
|
683
|
+
const regexp = new RegExp(find);
|
|
684
|
+
files = files.map((file) => file.replace(regexp, replacement));
|
|
685
|
+
} catch (error) {
|
|
686
|
+
if (error instanceof SyntaxError) {
|
|
687
|
+
logError(
|
|
688
|
+
error.message.replace(
|
|
689
|
+
"Invalid regular expression:",
|
|
690
|
+
`Invalid regular expression number ${i + 1} in config.`
|
|
691
|
+
)
|
|
692
|
+
);
|
|
693
|
+
} else {
|
|
694
|
+
logWarning(`Invalid regular expression number ${i + 1}`);
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
return files;
|
|
699
|
+
}
|
|
700
|
+
function handleOrder(config, files) {
|
|
701
|
+
files = files.sort((a, b) => a.localeCompare(b));
|
|
702
|
+
if (!config.order?.length) {
|
|
703
|
+
return files;
|
|
704
|
+
}
|
|
705
|
+
return files.sort((a, b) => sortPathWeight(config.order, b) - sortPathWeight(config.order, a));
|
|
706
|
+
}
|
|
707
|
+
function sortPathWeight(order, path) {
|
|
708
|
+
const orderIndex = order.findIndex((x) => path.startsWith(x));
|
|
709
|
+
if (orderIndex >= 0) {
|
|
710
|
+
return (order.length - orderIndex) * 100 - path.split("/").length;
|
|
711
|
+
}
|
|
712
|
+
return -path.split("/").length;
|
|
713
|
+
}
|
|
714
|
+
var TerminalColor = /* @__PURE__ */ ((TerminalColor2) => {
|
|
715
|
+
TerminalColor2[TerminalColor2["BLACK"] = 0] = "BLACK";
|
|
716
|
+
TerminalColor2[TerminalColor2["RED"] = 1] = "RED";
|
|
717
|
+
TerminalColor2[TerminalColor2["GREEN"] = 2] = "GREEN";
|
|
718
|
+
TerminalColor2[TerminalColor2["YELLOW"] = 3] = "YELLOW";
|
|
719
|
+
TerminalColor2[TerminalColor2["BLUE"] = 4] = "BLUE";
|
|
720
|
+
TerminalColor2[TerminalColor2["MAGENTA"] = 5] = "MAGENTA";
|
|
721
|
+
TerminalColor2[TerminalColor2["CYAN"] = 6] = "CYAN";
|
|
722
|
+
TerminalColor2[TerminalColor2["WHITE"] = 7] = "WHITE";
|
|
723
|
+
TerminalColor2[TerminalColor2["GRAY"] = 60] = "GRAY";
|
|
724
|
+
return TerminalColor2;
|
|
725
|
+
})(TerminalColor || {});
|
|
726
|
+
function colorize(text, foreground, background) {
|
|
727
|
+
if (background == null) {
|
|
728
|
+
return `\x1B[${30 + foreground}m${text}\x1B[0m`;
|
|
729
|
+
}
|
|
730
|
+
return `\x1B[${30 + foreground}m\x1B[${40 + background}m${text}\x1B[0m`;
|
|
731
|
+
}
|
|
732
|
+
function logError(message) {
|
|
733
|
+
console.log(colorize(message, TerminalColor.RED));
|
|
734
|
+
}
|
|
735
|
+
function logWarning(message) {
|
|
736
|
+
console.log(colorize(message, TerminalColor.YELLOW));
|
|
737
|
+
}
|
|
738
|
+
function logInfo(message) {
|
|
739
|
+
console.log(colorize(message, TerminalColor.BLUE));
|
|
740
|
+
}
|
|
741
|
+
function logValidationError(message, validation) {
|
|
742
|
+
const formatError = (e) => {
|
|
743
|
+
const property = e.path.replace("$input.", "");
|
|
744
|
+
if (e.expected === "undefined") {
|
|
745
|
+
return `Property '${property}' is not allowed in configuration`;
|
|
746
|
+
}
|
|
747
|
+
if (e.value === void 0) {
|
|
748
|
+
return `Missing required property '${property}' in configuration`;
|
|
749
|
+
}
|
|
750
|
+
return `Invalid type for property '${property}'`;
|
|
751
|
+
};
|
|
752
|
+
const errors = validation.errors.map((x) => ` ` + formatError(x)).join("\n");
|
|
753
|
+
const text = `${message}:
|
|
754
|
+
${errors}`;
|
|
755
|
+
logError(text);
|
|
756
|
+
}
|
|
757
|
+
export {
|
|
758
|
+
TerminalColor,
|
|
759
|
+
cliInit,
|
|
760
|
+
colorize,
|
|
761
|
+
generateBarrels,
|
|
762
|
+
logError,
|
|
763
|
+
logInfo,
|
|
764
|
+
logValidationError,
|
|
765
|
+
logWarning,
|
|
766
|
+
parseConfig,
|
|
767
|
+
runGenerateCommand,
|
|
768
|
+
runInitCommand,
|
|
769
|
+
validateConfig,
|
|
770
|
+
validateOutputConfig
|
|
771
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function cliInit(): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runInitCommand(baseConfigFilePath: string): Promise<void>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type Config = {
|
|
2
|
+
directories: {
|
|
3
|
+
path: string;
|
|
4
|
+
include: string[];
|
|
5
|
+
exclude: string[];
|
|
6
|
+
order?: string[];
|
|
7
|
+
indexFilePath?: string;
|
|
8
|
+
keepFileExtension?: boolean;
|
|
9
|
+
replace?: {
|
|
10
|
+
find: string;
|
|
11
|
+
replacement: string;
|
|
12
|
+
}[];
|
|
13
|
+
}[];
|
|
14
|
+
};
|
|
15
|
+
export declare const validateConfig: ((input: unknown) => import('typia').IValidation<Config>) & import('@standard-schema/spec').StandardSchemaV1<unknown, Config>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type OutputConfig = {
|
|
2
|
+
cwd: string;
|
|
3
|
+
directories: {
|
|
4
|
+
files: string[];
|
|
5
|
+
order?: string[];
|
|
6
|
+
}[];
|
|
7
|
+
};
|
|
8
|
+
export declare const validateOutputConfig: ((input: unknown) => import('typia').IValidation<OutputConfig>) & import('@standard-schema/spec').StandardSchemaV1<unknown, OutputConfig>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './cli/cli';
|
|
2
|
+
export * from './cli/commands/generate-command';
|
|
3
|
+
export * from './cli/commands/generate-command-options';
|
|
4
|
+
export * from './cli/commands/init-command';
|
|
5
|
+
export * from './config/config';
|
|
6
|
+
export * from './config/output-config';
|
|
7
|
+
export * from './config/parse-config';
|
|
8
|
+
export * from './generate/generate-barrels';
|
|
9
|
+
export * from './log/colorize';
|
|
10
|
+
export * from './log/log';
|
|
11
|
+
export * from './log/log-validation-error';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare enum TerminalColor {
|
|
2
|
+
BLACK = 0,
|
|
3
|
+
RED = 1,
|
|
4
|
+
GREEN = 2,
|
|
5
|
+
YELLOW = 3,
|
|
6
|
+
BLUE = 4,
|
|
7
|
+
MAGENTA = 5,
|
|
8
|
+
CYAN = 6,
|
|
9
|
+
WHITE = 7,
|
|
10
|
+
GRAY = 60
|
|
11
|
+
}
|
|
12
|
+
export declare function colorize(text: string, foreground: TerminalColor, background?: TerminalColor): string;
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "barrelize",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Automatically generating index (barrel) files",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "vite build",
|
|
7
|
+
"prepare": "ts-patch install",
|
|
8
|
+
"test": "vitest run"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git@github.com/nizami/barrelize"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"barrels",
|
|
16
|
+
"typescript",
|
|
17
|
+
"index",
|
|
18
|
+
"file"
|
|
19
|
+
],
|
|
20
|
+
"author": "Nizami",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"cac": "^6.7.14",
|
|
24
|
+
"glob": "^11.0.2",
|
|
25
|
+
"json5": "^2.2.3"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@ryoppippi/unplugin-typia": "^2.2.1",
|
|
29
|
+
"@types/node": "^22.15.17",
|
|
30
|
+
"ts-patch": "^3.3.0",
|
|
31
|
+
"typescript": "~5.8.3",
|
|
32
|
+
"typia": "^9.2.0",
|
|
33
|
+
"vite": "^6.3.5",
|
|
34
|
+
"vite-plugin-dts": "^4.5.3",
|
|
35
|
+
"vitest": "^3.1.3"
|
|
36
|
+
},
|
|
37
|
+
"bin": {
|
|
38
|
+
"barrelize": "./bin/cli.js"
|
|
39
|
+
},
|
|
40
|
+
"type": "module",
|
|
41
|
+
"sideEffects": false,
|
|
42
|
+
"files": [
|
|
43
|
+
"bin",
|
|
44
|
+
"lib"
|
|
45
|
+
],
|
|
46
|
+
"exports": {
|
|
47
|
+
".": {
|
|
48
|
+
"types": "./lib/src/index.d.ts",
|
|
49
|
+
"import": "./lib/index.js"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|