ts-repo-utils 1.0.0 → 1.0.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.
- package/README.md +284 -0
- package/dist/functions/assert-ext.d.mts +22 -0
- package/dist/functions/assert-ext.d.mts.map +1 -0
- package/dist/functions/assert-ext.mjs +73 -0
- package/dist/functions/assert-ext.mjs.map +1 -0
- package/dist/functions/assert-path-exists.d.mts +14 -0
- package/dist/functions/assert-path-exists.d.mts.map +1 -0
- package/dist/functions/assert-path-exists.mjs +30 -0
- package/dist/functions/assert-path-exists.mjs.map +1 -0
- package/dist/functions/assert-repo-is-dirty.d.mts +13 -0
- package/dist/functions/assert-repo-is-dirty.d.mts.map +1 -0
- package/dist/functions/assert-repo-is-dirty.mjs +58 -0
- package/dist/functions/assert-repo-is-dirty.mjs.map +1 -0
- package/dist/functions/exec-async.d.mts +20 -0
- package/dist/functions/exec-async.d.mts.map +1 -0
- package/dist/functions/exec-async.mjs +36 -0
- package/dist/functions/exec-async.mjs.map +1 -0
- package/dist/functions/format.d.mts +18 -0
- package/dist/functions/format.d.mts.map +1 -0
- package/dist/functions/format.mjs +204 -0
- package/dist/functions/format.mjs.map +1 -0
- package/dist/functions/gen-index.d.mts +21 -0
- package/dist/functions/gen-index.d.mts.map +1 -0
- package/dist/functions/gen-index.mjs +161 -0
- package/dist/functions/gen-index.mjs.map +1 -0
- package/dist/functions/index.d.mts +7 -0
- package/dist/functions/index.d.mts.map +1 -0
- package/dist/functions/index.mjs +7 -0
- package/dist/functions/index.mjs.map +1 -0
- package/dist/globals.d.mts +1 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +7 -0
- package/dist/index.mjs.map +1 -0
- package/dist/node-global.d.mts +14 -0
- package/dist/node-global.d.mts.map +1 -0
- package/dist/node-global.mjs +16 -0
- package/dist/node-global.mjs.map +1 -0
- package/dist/project-root-path.d.mts +2 -0
- package/dist/project-root-path.d.mts.map +1 -0
- package/dist/project-root-path.mjs +6 -0
- package/dist/project-root-path.mjs.map +1 -0
- package/dist/tsconfig.json +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,3 +1,287 @@
|
|
|
1
1
|
# ts-repo-utils
|
|
2
2
|
|
|
3
3
|
Utilities for TypeScript Repositories.
|
|
4
|
+
|
|
5
|
+
A comprehensive toolkit for managing TypeScript projects with strict ESM support, providing essential utilities for file validation, code formatting, git operations, and project automation.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install ts-repo-utils
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## API Reference
|
|
14
|
+
|
|
15
|
+
### Path and File System Utilities
|
|
16
|
+
|
|
17
|
+
#### `pathExists(filePath: string): Promise<boolean>`
|
|
18
|
+
|
|
19
|
+
Checks if a file or directory exists at the specified path.
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { pathExists } from 'ts-repo-utils';
|
|
23
|
+
|
|
24
|
+
const exists = await pathExists('./src/index.ts');
|
|
25
|
+
console.log(exists); // true or false
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
#### `assertPathExists(filePath: string, description?: string): Promise<void>`
|
|
29
|
+
|
|
30
|
+
Validates that a path exists and throws an error if it doesn't.
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import { assertPathExists } from 'ts-repo-utils';
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
await assertPathExists('./src/index.ts', 'Entry point file');
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.error('Entry point file does not exist');
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### File Extension Validation
|
|
43
|
+
|
|
44
|
+
#### `assertExt(config: CheckExtConfig): Promise<void>`
|
|
45
|
+
|
|
46
|
+
Validates that all files in specified directories have the correct extensions.
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { assertExt } from 'ts-repo-utils';
|
|
50
|
+
|
|
51
|
+
await assertExt({
|
|
52
|
+
directories: [
|
|
53
|
+
{
|
|
54
|
+
path: './src',
|
|
55
|
+
extension: '.ts',
|
|
56
|
+
ignorePatterns: ['*.d.ts', '*.test.ts'],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
path: './scripts',
|
|
60
|
+
extension: '.mjs',
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Configuration Type:**
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
type CheckExtConfig = DeepReadonly<{
|
|
70
|
+
directories: {
|
|
71
|
+
path: string; // Directory path to check
|
|
72
|
+
extension: string; // Expected file extension (including the dot)
|
|
73
|
+
ignorePatterns?: string[]; // Optional glob patterns to ignore
|
|
74
|
+
}[];
|
|
75
|
+
}>;
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Git Repository Utilities
|
|
79
|
+
|
|
80
|
+
#### `repoIsDirty(): Promise<boolean>`
|
|
81
|
+
|
|
82
|
+
Checks if the repository has uncommitted changes.
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import { repoIsDirty } from 'ts-repo-utils';
|
|
86
|
+
|
|
87
|
+
const isDirty = await repoIsDirty();
|
|
88
|
+
if (isDirty) {
|
|
89
|
+
console.log('Repository has uncommitted changes');
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
#### `assertRepoIsDirty(): Promise<void>`
|
|
94
|
+
|
|
95
|
+
Checks if repository is dirty and exits with code 1 if it is (shows changes and diff).
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
import { assertRepoIsDirty } from 'ts-repo-utils';
|
|
99
|
+
|
|
100
|
+
// Use in CI/build scripts to ensure clean state
|
|
101
|
+
await assertRepoIsDirty();
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Command Execution
|
|
105
|
+
|
|
106
|
+
#### `$(command: string, options?: ExecOptions): Promise<ExecResult>`
|
|
107
|
+
|
|
108
|
+
Executes a shell command asynchronously with timeout support and type-safe results.
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { $ } from 'ts-repo-utils';
|
|
112
|
+
|
|
113
|
+
const result = await $('npm test', { timeout: 60000 });
|
|
114
|
+
|
|
115
|
+
if (result.type === 'ok') {
|
|
116
|
+
console.log('Tests passed:', result.stdout);
|
|
117
|
+
} else {
|
|
118
|
+
console.error('Tests failed:', result.exception.message);
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Types:**
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
type ExecOptions = Readonly<{
|
|
126
|
+
silent?: boolean; // Don't log command/output (default: false)
|
|
127
|
+
timeout?: number; // Timeout in milliseconds (default: 30000)
|
|
128
|
+
}>;
|
|
129
|
+
|
|
130
|
+
type ExecResult = Readonly<
|
|
131
|
+
| { type: 'ok'; stdout: string; stderr: string }
|
|
132
|
+
| { type: 'error'; exception: ExecException }
|
|
133
|
+
>;
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Code Formatting Utilities
|
|
137
|
+
|
|
138
|
+
#### `formatFiles(pathGlob: string): Promise<'ok' | 'err'>`
|
|
139
|
+
|
|
140
|
+
Format files matching a glob pattern using Prettier.
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
import { formatFiles } from 'ts-repo-utils';
|
|
144
|
+
|
|
145
|
+
// Format all TypeScript files in src
|
|
146
|
+
await formatFiles('src/**/*.ts');
|
|
147
|
+
|
|
148
|
+
// Format specific files
|
|
149
|
+
await formatFiles('src/{index,utils}.ts');
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### `formatChanged(): Promise<'ok' | 'err'>`
|
|
153
|
+
|
|
154
|
+
Format only files that have been changed according to git status.
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
import { formatChanged } from 'ts-repo-utils';
|
|
158
|
+
|
|
159
|
+
// Format only modified files
|
|
160
|
+
await formatChanged();
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
#### `formatDiffFrom(base?: string): Promise<'ok' | 'err'>`
|
|
164
|
+
|
|
165
|
+
Format only files that differ from the specified base branch or commit.
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
import { formatDiffFrom } from 'ts-repo-utils';
|
|
169
|
+
|
|
170
|
+
// Format files different from main branch
|
|
171
|
+
await formatDiffFrom('main');
|
|
172
|
+
|
|
173
|
+
// Format files different from specific commit
|
|
174
|
+
await formatDiffFrom('abc123');
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Index File Generation
|
|
178
|
+
|
|
179
|
+
#### `genIndex(config: GenIndexConfig): Promise<void>`
|
|
180
|
+
|
|
181
|
+
Generates index.mts files recursively in target directories with automatic barrel exports.
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
import { genIndex } from 'ts-repo-utils';
|
|
185
|
+
|
|
186
|
+
await genIndex({
|
|
187
|
+
targetDirectory: './src',
|
|
188
|
+
sourceExtension: '.ts',
|
|
189
|
+
exportExtension: '.js',
|
|
190
|
+
excludePatterns: ['*.test.ts', '*.spec.ts'],
|
|
191
|
+
});
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Configuration Type:**
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
type GenIndexConfig = DeepReadonly<{
|
|
198
|
+
targetDirectory: string | string[]; // Target directories to generate index files for
|
|
199
|
+
sourceExtension?: `.${string}`; // File extension of source files (default: '.mts')
|
|
200
|
+
exportExtension?: `.${string}`; // Extension to use in exports (default: '.mjs')
|
|
201
|
+
excludePatterns?: string[]; // Glob patterns to exclude (default: excludes .d.* and .test.*)
|
|
202
|
+
}>;
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**Features:**
|
|
206
|
+
|
|
207
|
+
- Validates file extensions before generation
|
|
208
|
+
- Creates barrel exports for all subdirectories
|
|
209
|
+
- Supports complex glob exclusion patterns
|
|
210
|
+
- Automatically formats generated files
|
|
211
|
+
- Works with both single directories and directory arrays
|
|
212
|
+
|
|
213
|
+
## Key Features
|
|
214
|
+
|
|
215
|
+
- **Type Safety**: All functions use strict TypeScript types with readonly parameters
|
|
216
|
+
- **Error Handling**: Comprehensive error handling with descriptive messages
|
|
217
|
+
- **Git Integration**: Built-in git status and diff utilities
|
|
218
|
+
- **Formatting**: Prettier integration with configuration resolution
|
|
219
|
+
- **ESM Support**: Designed for ES modules with .mts/.mjs extension handling
|
|
220
|
+
- **Concurrent Processing**: Uses Promise.all for performance optimization
|
|
221
|
+
- **Configurable**: Flexible configuration options with sensible defaults
|
|
222
|
+
- **Console Feedback**: Informative logging throughout operations
|
|
223
|
+
|
|
224
|
+
## Common Patterns
|
|
225
|
+
|
|
226
|
+
### Pre-commit Hook
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
import { formatChanged, assertExt, repoIsDirty } from 'ts-repo-utils';
|
|
230
|
+
|
|
231
|
+
// Format changed files
|
|
232
|
+
await formatChanged();
|
|
233
|
+
|
|
234
|
+
// Validate file extensions
|
|
235
|
+
await assertExt({
|
|
236
|
+
directories: [{ path: './src', extension: '.ts' }],
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
// Ensure no uncommitted changes remain
|
|
240
|
+
await assertRepoIsDirty();
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Build Pipeline
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
import { assertExt, genIndex, $, formatFiles } from 'ts-repo-utils';
|
|
247
|
+
|
|
248
|
+
// Validate extensions
|
|
249
|
+
await assertExt({
|
|
250
|
+
directories: [
|
|
251
|
+
{ path: './src', extension: '.ts' },
|
|
252
|
+
{ path: './scripts', extension: '.mjs' },
|
|
253
|
+
],
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
// Generate barrel exports
|
|
257
|
+
await genIndex({ targetDirectory: './src' });
|
|
258
|
+
|
|
259
|
+
// Type check
|
|
260
|
+
await $('tsc --noEmit');
|
|
261
|
+
|
|
262
|
+
// Build
|
|
263
|
+
await $('rollup -c');
|
|
264
|
+
|
|
265
|
+
// Format output
|
|
266
|
+
await formatFiles('dist/**/*.js');
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Project Validation
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
import { pathExists, assertPathExists, repoIsDirty } from 'ts-repo-utils';
|
|
273
|
+
|
|
274
|
+
// Check required files exist
|
|
275
|
+
await assertPathExists('./package.json', 'Package manifest');
|
|
276
|
+
await assertPathExists('./tsconfig.json', 'TypeScript config');
|
|
277
|
+
|
|
278
|
+
// Verify clean repository state
|
|
279
|
+
const isDirty = await repoIsDirty();
|
|
280
|
+
if (isDirty) {
|
|
281
|
+
throw new Error('Repository has uncommitted changes');
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
## License
|
|
286
|
+
|
|
287
|
+
Apache-2.0
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import '../node-global.mjs';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for directory extension checking.
|
|
4
|
+
*/
|
|
5
|
+
export type CheckExtConfig = DeepReadonly<{
|
|
6
|
+
/** Array of directory paths and their expected extensions */
|
|
7
|
+
directories: {
|
|
8
|
+
/** Directory path to check */
|
|
9
|
+
path: string;
|
|
10
|
+
/** Expected file extension (including the dot) */
|
|
11
|
+
extension: string;
|
|
12
|
+
/** Optional glob patterns to ignore (defaults to ['tsconfig.json', 'globals.d.*']) */
|
|
13
|
+
ignorePatterns?: string[];
|
|
14
|
+
}[];
|
|
15
|
+
}>;
|
|
16
|
+
/**
|
|
17
|
+
* Validates that all files in specified directories have the correct extensions.
|
|
18
|
+
* @param config - Configuration specifying directories and expected extensions.
|
|
19
|
+
* @throws Error with details of all incorrect files found.
|
|
20
|
+
*/
|
|
21
|
+
export declare const assertExt: (config: CheckExtConfig) => Promise<void>;
|
|
22
|
+
//# sourceMappingURL=assert-ext.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assert-ext.d.mts","sourceRoot":"","sources":["../../src/functions/assert-ext.mts"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,CAAC;AAG5B;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,YAAY,CAAC;IACxC,6DAA6D;IAC7D,WAAW,EAAE;QACX,8BAA8B;QAC9B,IAAI,EAAE,MAAM,CAAC;QACb,kDAAkD;QAClD,SAAS,EAAE,MAAM,CAAC;QAClB,sFAAsF;QACtF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;KAC3B,EAAE,CAAC;CACL,CAAC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,SAAS,GAAU,QAAQ,cAAc,KAAG,OAAO,CAAC,IAAI,CA2DpE,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import '../node-global.mjs';
|
|
2
|
+
import { assertPathExists } from './assert-path-exists.mjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Validates that all files in specified directories have the correct extensions.
|
|
6
|
+
* @param config - Configuration specifying directories and expected extensions.
|
|
7
|
+
* @throws Error with details of all incorrect files found.
|
|
8
|
+
*/
|
|
9
|
+
const assertExt = async (config) => {
|
|
10
|
+
const allIncorrectFiles = [];
|
|
11
|
+
// Check all directories in parallel
|
|
12
|
+
const results = await Promise.all(config.directories.map(async ({ path: dir, extension, ignorePatterns }) => {
|
|
13
|
+
try {
|
|
14
|
+
return await getFilesWithIncorrectExtension(dir, extension, ignorePatterns);
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
console.error(`Failed to check directory ${dir}: ${String(error)}`);
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
}));
|
|
21
|
+
// Collect all incorrect files
|
|
22
|
+
results.forEach((incorrectFiles) => {
|
|
23
|
+
allIncorrectFiles.push(...incorrectFiles);
|
|
24
|
+
});
|
|
25
|
+
if (allIncorrectFiles.length > 0) {
|
|
26
|
+
const generateErrorMessage = () => {
|
|
27
|
+
// Group directories by extension for a cleaner message
|
|
28
|
+
const extensionGroups = new Map();
|
|
29
|
+
for (const { path: dirPath, extension } of config.directories) {
|
|
30
|
+
const relativePath = path.relative(process.cwd(), dirPath);
|
|
31
|
+
if (!extensionGroups.has(extension)) {
|
|
32
|
+
extensionGroups.set(extension, []);
|
|
33
|
+
}
|
|
34
|
+
extensionGroups.get(extension)?.push(relativePath);
|
|
35
|
+
}
|
|
36
|
+
// Generate message parts for each extension
|
|
37
|
+
const messageParts = Array.from(extensionGroups.entries()).map(([ext, dirs]) => {
|
|
38
|
+
const dirList = dirs.length === 1 ? dirs[0] : dirs.join(', ');
|
|
39
|
+
return `${dirList} should have ${ext} extension`;
|
|
40
|
+
});
|
|
41
|
+
return `All files in ${messageParts.join(' and ')}.`;
|
|
42
|
+
};
|
|
43
|
+
const errorMessage = [
|
|
44
|
+
'Files with incorrect extensions found:',
|
|
45
|
+
...allIncorrectFiles.map((file) => ` - ${file}`),
|
|
46
|
+
'',
|
|
47
|
+
generateErrorMessage(),
|
|
48
|
+
].join('\n');
|
|
49
|
+
throw new Error(errorMessage);
|
|
50
|
+
}
|
|
51
|
+
echo('✓ All files have correct extensions');
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Checks if all files in a directory have the expected extension.
|
|
55
|
+
* @param dir - The directory to check.
|
|
56
|
+
* @param expectedExtension - The expected file extension.
|
|
57
|
+
* @param ignorePatterns - Optional glob patterns to ignore.
|
|
58
|
+
* @returns Array of files with incorrect extensions.
|
|
59
|
+
*/
|
|
60
|
+
const getFilesWithIncorrectExtension = async (dir, expectedExtension, ignorePatterns) => {
|
|
61
|
+
await assertPathExists(dir, 'Directory');
|
|
62
|
+
const defaultIgnorePatterns = ['tsconfig.json', 'globals.d.*'];
|
|
63
|
+
const finalIgnorePatterns = ignorePatterns ?? defaultIgnorePatterns;
|
|
64
|
+
// Convert relative patterns to absolute paths for the glob ignore option
|
|
65
|
+
const absoluteIgnorePatterns = finalIgnorePatterns.map((pattern) => path.isAbsolute(pattern) ? pattern : `${dir}/${pattern}`);
|
|
66
|
+
const files = await glob(`${dir}/**/*`, {
|
|
67
|
+
ignore: absoluteIgnorePatterns,
|
|
68
|
+
});
|
|
69
|
+
return files.filter((file) => !file.endsWith(expectedExtension));
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export { assertExt };
|
|
73
|
+
//# sourceMappingURL=assert-ext.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assert-ext.mjs","sources":["../../src/functions/assert-ext.mts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks if a file or directory exists.
|
|
3
|
+
* @param filePath - The path to check.
|
|
4
|
+
* @returns True if the path exists.
|
|
5
|
+
*/
|
|
6
|
+
export declare const pathExists: (filePath: string) => Promise<boolean>;
|
|
7
|
+
/**
|
|
8
|
+
* Validates that a path exists and throws if it doesn't.
|
|
9
|
+
* @param filePath - The path to validate.
|
|
10
|
+
* @param description - Description for error message.
|
|
11
|
+
* @throws Error if path doesn't exist.
|
|
12
|
+
*/
|
|
13
|
+
export declare const assertPathExists: (filePath: string, description?: string) => Promise<void>;
|
|
14
|
+
//# sourceMappingURL=assert-path-exists.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assert-path-exists.d.mts","sourceRoot":"","sources":["../../src/functions/assert-path-exists.mts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAU,UAAU,MAAM,KAAG,OAAO,CAAC,OAAO,CAOlE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAC3B,UAAU,MAAM,EAChB,oBAAoB,KACnB,OAAO,CAAC,IAAI,CAId,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as fs_ from 'node:fs/promises';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Checks if a file or directory exists.
|
|
5
|
+
* @param filePath - The path to check.
|
|
6
|
+
* @returns True if the path exists.
|
|
7
|
+
*/
|
|
8
|
+
const pathExists = async (filePath) => {
|
|
9
|
+
try {
|
|
10
|
+
await fs_.access(filePath);
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Validates that a path exists and throws if it doesn't.
|
|
19
|
+
* @param filePath - The path to validate.
|
|
20
|
+
* @param description - Description for error message.
|
|
21
|
+
* @throws Error if path doesn't exist.
|
|
22
|
+
*/
|
|
23
|
+
const assertPathExists = async (filePath, description = 'Path') => {
|
|
24
|
+
if (!(await pathExists(filePath))) {
|
|
25
|
+
throw new Error(`${description} does not exist: ${filePath}`);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export { assertPathExists, pathExists };
|
|
30
|
+
//# sourceMappingURL=assert-path-exists.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assert-path-exists.mjs","sources":["../../src/functions/assert-path-exists.mts"],"sourcesContent":[null],"names":["fs"],"mappings":";;AAEA;;;;AAIG;MACU,UAAU,GAAG,OAAO,QAAgB,KAAsB;AACrE,IAAA,IAAI;AACF,QAAA,MAAMA,GAAE,CAAC,MAAM,CAAC,QAAQ,CAAC;AACzB,QAAA,OAAO,IAAI;;AACX,IAAA,MAAM;AACN,QAAA,OAAO,KAAK;;AAEhB;AAEA;;;;;AAKG;AACI,MAAM,gBAAgB,GAAG,OAC9B,QAAgB,EAChB,WAAW,GAAG,MAAM,KACH;IACjB,IAAI,EAAE,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC,EAAE;QACjC,MAAM,IAAI,KAAK,CAAC,CAAA,EAAG,WAAW,CAAoB,iBAAA,EAAA,QAAQ,CAAE,CAAA,CAAC;;AAEjE;;;;"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import '../node-global.mjs';
|
|
2
|
+
/**
|
|
3
|
+
* Checks if the repository has uncommitted changes.
|
|
4
|
+
* @returns True if the repo is dirty, false otherwise.
|
|
5
|
+
* @throws Error if git command fails.
|
|
6
|
+
*/
|
|
7
|
+
export declare const repoIsDirty: () => Promise<boolean>;
|
|
8
|
+
/**
|
|
9
|
+
* Checks if the repository is dirty and exits with code 1 if it is.
|
|
10
|
+
* @throws Error if git command fails.
|
|
11
|
+
*/
|
|
12
|
+
export declare const assertRepoIsDirty: () => Promise<void>;
|
|
13
|
+
//# sourceMappingURL=assert-repo-is-dirty.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assert-repo-is-dirty.d.mts","sourceRoot":"","sources":["../../src/functions/assert-repo-is-dirty.mts"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,CAAC;AAE5B;;;;GAIG;AACH,eAAO,MAAM,WAAW,QAAa,OAAO,CAAC,OAAO,CAGnD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAAa,OAAO,CAAC,IAAI,CA6BtD,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import '../node-global.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Checks if the repository has uncommitted changes.
|
|
5
|
+
* @returns True if the repo is dirty, false otherwise.
|
|
6
|
+
* @throws Error if git command fails.
|
|
7
|
+
*/
|
|
8
|
+
const repoIsDirty = async () => {
|
|
9
|
+
const status = await getGitStatus();
|
|
10
|
+
return status.isDirty;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Checks if the repository is dirty and exits with code 1 if it is.
|
|
14
|
+
* @throws Error if git command fails.
|
|
15
|
+
*/
|
|
16
|
+
const assertRepoIsDirty = async () => {
|
|
17
|
+
try {
|
|
18
|
+
const status = await getGitStatus();
|
|
19
|
+
if (!status.isDirty) {
|
|
20
|
+
echo('Repo is clean\n');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
echo('Repo is dirty\n');
|
|
24
|
+
echo('Changed files:\n');
|
|
25
|
+
echo(status.stdout);
|
|
26
|
+
// Show files not tracked by git and unstaged changes
|
|
27
|
+
const addResult = await $('git add -N .');
|
|
28
|
+
if (addResult.type === 'error') {
|
|
29
|
+
echo('Warning: Failed to add untracked files for diff\n');
|
|
30
|
+
}
|
|
31
|
+
const diffResult = await $('git diff');
|
|
32
|
+
if (diffResult.type === 'error') {
|
|
33
|
+
echo('Warning: Failed to show diff\n');
|
|
34
|
+
}
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
echo(`Error checking repository status: ${String(error)}\n`);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Gets the git status of the repository.
|
|
44
|
+
* @returns An object containing status information.
|
|
45
|
+
*/
|
|
46
|
+
const getGitStatus = async () => {
|
|
47
|
+
const res = await $('git status --porcelain');
|
|
48
|
+
if (res.type === 'error') {
|
|
49
|
+
throw new Error(`Failed to get git status: ${res.exception.message}`);
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
isDirty: res.stdout.trim() !== '',
|
|
53
|
+
stdout: res.stdout,
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export { assertRepoIsDirty, repoIsDirty };
|
|
58
|
+
//# sourceMappingURL=assert-repo-is-dirty.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assert-repo-is-dirty.mjs","sources":["../../src/functions/assert-repo-is-dirty.mts"],"sourcesContent":[null],"names":[],"mappings":";;AAEA;;;;AAIG;AACU,MAAA,WAAW,GAAG,YAA6B;AACtD,IAAA,MAAM,MAAM,GAAG,MAAM,YAAY,EAAE;IACnC,OAAO,MAAM,CAAC,OAAO;AACvB;AAEA;;;AAGG;AACU,MAAA,iBAAiB,GAAG,YAA0B;AACzD,IAAA,IAAI;AACF,QAAA,MAAM,MAAM,GAAG,MAAM,YAAY,EAAE;AAEnC,QAAA,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;YACnB,IAAI,CAAC,iBAAiB,CAAC;YACvB;;QAGF,IAAI,CAAC,iBAAiB,CAAC;QACvB,IAAI,CAAC,kBAAkB,CAAC;AACxB,QAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;;AAGnB,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,cAAc,CAAC;AACzC,QAAA,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,EAAE;YAC9B,IAAI,CAAC,mDAAmD,CAAC;;AAG3D,QAAA,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,UAAU,CAAC;AACtC,QAAA,IAAI,UAAU,CAAC,IAAI,KAAK,OAAO,EAAE;YAC/B,IAAI,CAAC,gCAAgC,CAAC;;AAGxC,QAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;;IACf,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,qCAAqC,MAAM,CAAC,KAAK,CAAC,CAAA,EAAA,CAAI,CAAC;AAC5D,QAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;;AAEnB;AAEA;;;AAGG;AACH,MAAM,YAAY,GAAG,YAGhB;AACH,IAAA,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,wBAAwB,CAAC;AAE7C,IAAA,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE;QACxB,MAAM,IAAI,KAAK,CAAC,CAA6B,0BAAA,EAAA,GAAG,CAAC,SAAS,CAAC,OAAO,CAAE,CAAA,CAAC;;IAGvE,OAAO;QACL,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE;QACjC,MAAM,EAAE,GAAG,CAAC,MAAM;KACnB;AACH,CAAC;;;;"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ExecException } from 'node:child_process';
|
|
2
|
+
export type ExecResult = Readonly<{
|
|
3
|
+
type: 'ok';
|
|
4
|
+
stdout: string;
|
|
5
|
+
stderr: string;
|
|
6
|
+
} | {
|
|
7
|
+
type: 'error';
|
|
8
|
+
exception: ExecException;
|
|
9
|
+
}>;
|
|
10
|
+
/**
|
|
11
|
+
* Executes a shell command asynchronously.
|
|
12
|
+
* @param cmd - The command to execute.
|
|
13
|
+
* @param options - Optional configuration for command execution.
|
|
14
|
+
* @returns A promise that resolves with the command result.
|
|
15
|
+
*/
|
|
16
|
+
export declare const $: (cmd: string, options?: Readonly<{
|
|
17
|
+
silent?: boolean;
|
|
18
|
+
timeout?: number;
|
|
19
|
+
}>) => Promise<ExecResult>;
|
|
20
|
+
//# sourceMappingURL=exec-async.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec-async.d.mts","sourceRoot":"","sources":["../../src/functions/exec-async.mts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE9D,MAAM,MAAM,UAAU,GAAG,QAAQ,CAC7B;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,aAAa,CAAA;CAAE,CAC9C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,CAAC,GACZ,KAAK,MAAM,EACX,UAAS,QAAQ,CAAC;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAM,KAC7D,OAAO,CAAC,UAAU,CA2BpB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { exec } from 'node:child_process';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Executes a shell command asynchronously.
|
|
5
|
+
* @param cmd - The command to execute.
|
|
6
|
+
* @param options - Optional configuration for command execution.
|
|
7
|
+
* @returns A promise that resolves with the command result.
|
|
8
|
+
*/
|
|
9
|
+
const $ = (cmd, options = {}) => {
|
|
10
|
+
const { silent = false, timeout = 30000 } = options;
|
|
11
|
+
if (!silent) {
|
|
12
|
+
console.log(`$ ${cmd}`);
|
|
13
|
+
}
|
|
14
|
+
return new Promise((resolve) => {
|
|
15
|
+
const execOptions = { timeout };
|
|
16
|
+
exec(cmd, execOptions, (error, stdout, stderr) => {
|
|
17
|
+
if (!silent) {
|
|
18
|
+
if (stdout !== '') {
|
|
19
|
+
console.log(stdout);
|
|
20
|
+
}
|
|
21
|
+
if (stderr !== '') {
|
|
22
|
+
console.error(stderr);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (error !== null) {
|
|
26
|
+
resolve({ type: 'error', exception: error });
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
resolve({ type: 'ok', stdout, stderr });
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export { $ };
|
|
36
|
+
//# sourceMappingURL=exec-async.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec-async.mjs","sources":["../../src/functions/exec-async.mts"],"sourcesContent":[null],"names":[],"mappings":";;AAOA;;;;;AAKG;AACU,MAAA,CAAC,GAAG,CACf,GAAW,EACX,OAAA,GAA4D,EAAE,KACvC;IACvB,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,OAAO;IAEnD,IAAI,CAAC,MAAM,EAAE;AACX,QAAA,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,CAAA,CAAE,CAAC;;AAGzB,IAAA,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAI;AAC7B,QAAA,MAAM,WAAW,GAAG,EAAE,OAAO,EAAE;AAE/B,QAAA,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,KAAI;YAC/C,IAAI,CAAC,MAAM,EAAE;AACX,gBAAA,IAAI,MAAM,KAAK,EAAE,EAAE;AACjB,oBAAA,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;;AAErB,gBAAA,IAAI,MAAM,KAAK,EAAE,EAAE;AACjB,oBAAA,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;;;AAIzB,YAAA,IAAI,KAAK,KAAK,IAAI,EAAE;gBAClB,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;;iBACvC;gBACL,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;;AAE3C,SAAC,CAAC;AACJ,KAAC,CAAC;AACJ;;;;"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format files matching the given glob pattern using Prettier
|
|
3
|
+
* @param pathGlob - Glob pattern to match files
|
|
4
|
+
* @returns 'ok' if successful, 'err' if any errors occurred
|
|
5
|
+
*/
|
|
6
|
+
export declare const formatFiles: (pathGlob: string) => Promise<"ok" | "err">;
|
|
7
|
+
/**
|
|
8
|
+
* Format only files that have been changed (git status)
|
|
9
|
+
* @returns 'ok' if successful, 'err' if any errors occurred
|
|
10
|
+
*/
|
|
11
|
+
export declare const formatChanged: () => Promise<"ok" | "err">;
|
|
12
|
+
/**
|
|
13
|
+
* Format only files that differ from the specified base branch or commit
|
|
14
|
+
* @param base - Base branch name or commit hash to compare against (defaults to 'main')
|
|
15
|
+
* @returns 'ok' if successful, 'err' if any errors occurred
|
|
16
|
+
*/
|
|
17
|
+
export declare const formatDiffFrom: (base?: string) => Promise<"ok" | "err">;
|
|
18
|
+
//# sourceMappingURL=format.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.mts","sourceRoot":"","sources":["../../src/functions/format.mts"],"names":[],"mappings":"AAQA;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAU,UAAU,MAAM,KAAG,OAAO,CAAC,IAAI,GAAG,KAAK,CA6DxE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,QAAa,OAAO,CAAC,IAAI,GAAG,KAAK,CAiF1D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,GACzB,OAAM,MAAe,KACpB,OAAO,CAAC,IAAI,GAAG,KAAK,CAsEtB,CAAC"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import glob_ from 'fast-glob';
|
|
2
|
+
import { exec } from 'node:child_process';
|
|
3
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { promisify } from 'node:util';
|
|
5
|
+
import * as prettier from 'prettier';
|
|
6
|
+
|
|
7
|
+
const execAsync = promisify(exec);
|
|
8
|
+
/**
|
|
9
|
+
* Format files matching the given glob pattern using Prettier
|
|
10
|
+
* @param pathGlob - Glob pattern to match files
|
|
11
|
+
* @returns 'ok' if successful, 'err' if any errors occurred
|
|
12
|
+
*/
|
|
13
|
+
const formatFiles = async (pathGlob) => {
|
|
14
|
+
try {
|
|
15
|
+
// Find all files matching the glob
|
|
16
|
+
const files = await glob_(pathGlob, {
|
|
17
|
+
absolute: true,
|
|
18
|
+
ignore: ['**/node_modules/**', '**/.git/**'],
|
|
19
|
+
dot: true,
|
|
20
|
+
});
|
|
21
|
+
if (files.length === 0) {
|
|
22
|
+
console.log('No files found matching pattern:', pathGlob);
|
|
23
|
+
return 'ok';
|
|
24
|
+
}
|
|
25
|
+
console.log(`Formatting ${files.length} files...`);
|
|
26
|
+
// Format each file
|
|
27
|
+
const results = await Promise.allSettled(files.map(async (filePath) => {
|
|
28
|
+
try {
|
|
29
|
+
// Read file content
|
|
30
|
+
const content = await readFile(filePath, 'utf8');
|
|
31
|
+
// Resolve prettier config for this file
|
|
32
|
+
const options = await prettier.resolveConfig(filePath);
|
|
33
|
+
// Check if file is ignored by prettier
|
|
34
|
+
const fileInfo = await prettier.getFileInfo(filePath, {
|
|
35
|
+
ignorePath: '.prettierignore',
|
|
36
|
+
});
|
|
37
|
+
if (fileInfo.ignored) {
|
|
38
|
+
console.log(`Skipping ignored file: ${filePath}`);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
// Format the content
|
|
42
|
+
const formatted = await prettier.format(content, {
|
|
43
|
+
...options,
|
|
44
|
+
filepath: filePath,
|
|
45
|
+
});
|
|
46
|
+
// Only write if content changed
|
|
47
|
+
if (formatted !== content) {
|
|
48
|
+
await writeFile(filePath, formatted, 'utf8');
|
|
49
|
+
console.log(`Formatted: ${filePath}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.error(`Error formatting ${filePath}:`, error);
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
}));
|
|
57
|
+
// Check if any formatting failed
|
|
58
|
+
const hasErrors = results.some((result) => result.status === 'rejected');
|
|
59
|
+
return hasErrors ? 'err' : 'ok';
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
console.error('Error in formatFiles:', error);
|
|
63
|
+
return 'err';
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Format only files that have been changed (git status)
|
|
68
|
+
* @returns 'ok' if successful, 'err' if any errors occurred
|
|
69
|
+
*/
|
|
70
|
+
const formatChanged = async () => {
|
|
71
|
+
try {
|
|
72
|
+
// Get changed files from git status
|
|
73
|
+
const { stdout, stderr } = await execAsync('git status --porcelain');
|
|
74
|
+
if (stderr !== '') {
|
|
75
|
+
console.error('Git error:', stderr);
|
|
76
|
+
return 'err';
|
|
77
|
+
}
|
|
78
|
+
// Parse git status output
|
|
79
|
+
const files = stdout
|
|
80
|
+
.split('\n')
|
|
81
|
+
.filter((line) => line.trim() !== '')
|
|
82
|
+
.map((line) => {
|
|
83
|
+
// Status format: "XY filename" where X and Y are status codes
|
|
84
|
+
const match = /^..\s+(.+)$/u.exec(line);
|
|
85
|
+
return match?.[1];
|
|
86
|
+
})
|
|
87
|
+
.filter((file) =>
|
|
88
|
+
// Filter out deleted files (status starts with 'D')
|
|
89
|
+
file !== undefined && !stdout.includes(`D ${file}`));
|
|
90
|
+
if (files.length === 0) {
|
|
91
|
+
console.log('No changed files to format');
|
|
92
|
+
return 'ok';
|
|
93
|
+
}
|
|
94
|
+
console.log('Formatting changed files:', files);
|
|
95
|
+
// Format each changed file
|
|
96
|
+
const results = await Promise.allSettled(files.map(async (filePath) => {
|
|
97
|
+
try {
|
|
98
|
+
// Check if file exists and is not deleted
|
|
99
|
+
const content = await readFile(filePath, 'utf8').catch(() => null);
|
|
100
|
+
if (content === null) {
|
|
101
|
+
console.log(`Skipping non-existent file: ${filePath}`);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
// Resolve prettier config for this file
|
|
105
|
+
const options = await prettier.resolveConfig(filePath);
|
|
106
|
+
// Check if file is ignored by prettier
|
|
107
|
+
const fileInfo = await prettier.getFileInfo(filePath, {
|
|
108
|
+
ignorePath: '.prettierignore',
|
|
109
|
+
});
|
|
110
|
+
if (fileInfo.ignored) {
|
|
111
|
+
console.log(`Skipping ignored file: ${filePath}`);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
// Format the content
|
|
115
|
+
const formatted = await prettier.format(content, {
|
|
116
|
+
...options,
|
|
117
|
+
filepath: filePath,
|
|
118
|
+
});
|
|
119
|
+
// Only write if content changed
|
|
120
|
+
if (formatted !== content) {
|
|
121
|
+
await writeFile(filePath, formatted, 'utf8');
|
|
122
|
+
console.log(`Formatted: ${filePath}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
console.error(`Error formatting ${filePath}:`, error);
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
129
|
+
}));
|
|
130
|
+
// Check if any formatting failed
|
|
131
|
+
const hasErrors = results.some((result) => result.status === 'rejected');
|
|
132
|
+
return hasErrors ? 'err' : 'ok';
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
console.error('Error in formatChanged:', error);
|
|
136
|
+
return 'err';
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* Format only files that differ from the specified base branch or commit
|
|
141
|
+
* @param base - Base branch name or commit hash to compare against (defaults to 'main')
|
|
142
|
+
* @returns 'ok' if successful, 'err' if any errors occurred
|
|
143
|
+
*/
|
|
144
|
+
const formatDiffFrom = async (base = 'main') => {
|
|
145
|
+
try {
|
|
146
|
+
// Get files that differ from base branch/commit (excluding deleted files)
|
|
147
|
+
const { stdout, stderr } = await execAsync(`git diff --name-only ${base} --diff-filter=d`);
|
|
148
|
+
if (stderr !== '') {
|
|
149
|
+
console.error('Git error:', stderr);
|
|
150
|
+
return 'err';
|
|
151
|
+
}
|
|
152
|
+
// Parse git diff output
|
|
153
|
+
const files = stdout
|
|
154
|
+
.split('\n')
|
|
155
|
+
.map((line) => line.trim())
|
|
156
|
+
.filter((line) => line !== '');
|
|
157
|
+
if (files.length === 0) {
|
|
158
|
+
console.log(`No files differ from ${base}`);
|
|
159
|
+
return 'ok';
|
|
160
|
+
}
|
|
161
|
+
console.log(`Formatting files that differ from ${base}:`, files);
|
|
162
|
+
// Format each file
|
|
163
|
+
const results = await Promise.allSettled(files.map(async (filePath) => {
|
|
164
|
+
try {
|
|
165
|
+
// Read file content
|
|
166
|
+
const content = await readFile(filePath, 'utf8');
|
|
167
|
+
// Resolve prettier config for this file
|
|
168
|
+
const options = await prettier.resolveConfig(filePath);
|
|
169
|
+
// Check if file is ignored by prettier
|
|
170
|
+
const fileInfo = await prettier.getFileInfo(filePath, {
|
|
171
|
+
ignorePath: '.prettierignore',
|
|
172
|
+
});
|
|
173
|
+
if (fileInfo.ignored) {
|
|
174
|
+
console.log(`Skipping ignored file: ${filePath}`);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
// Format the content
|
|
178
|
+
const formatted = await prettier.format(content, {
|
|
179
|
+
...options,
|
|
180
|
+
filepath: filePath,
|
|
181
|
+
});
|
|
182
|
+
// Only write if content changed
|
|
183
|
+
if (formatted !== content) {
|
|
184
|
+
await writeFile(filePath, formatted, 'utf8');
|
|
185
|
+
console.log(`Formatted: ${filePath}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
console.error(`Error formatting ${filePath}:`, error);
|
|
190
|
+
throw error;
|
|
191
|
+
}
|
|
192
|
+
}));
|
|
193
|
+
// Check if any formatting failed
|
|
194
|
+
const hasErrors = results.some((result) => result.status === 'rejected');
|
|
195
|
+
return hasErrors ? 'err' : 'ok';
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
console.error('Error in formatDiffFrom:', error);
|
|
199
|
+
return 'err';
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
export { formatChanged, formatDiffFrom, formatFiles };
|
|
204
|
+
//# sourceMappingURL=format.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.mjs","sources":["../../src/functions/format.mts"],"sourcesContent":[null],"names":["glob"],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import '../node-global.mjs';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for index file generation.
|
|
4
|
+
*/
|
|
5
|
+
export type GenIndexConfig = DeepReadonly<{
|
|
6
|
+
/** Target directories to generate index files for (string or array of strings) */
|
|
7
|
+
targetDirectory: string | string[];
|
|
8
|
+
/** File extension of source files to export (default: '.mts') */
|
|
9
|
+
sourceExtension?: `.${string}`;
|
|
10
|
+
/** File extension to use in export statements (default: '.mjs') */
|
|
11
|
+
exportExtension?: `.${string}`;
|
|
12
|
+
/** Glob patterns of files to exclude from exports (default: excludes .d.* and .test.* files) */
|
|
13
|
+
excludePatterns?: string[];
|
|
14
|
+
}>;
|
|
15
|
+
/**
|
|
16
|
+
* Generates index.mts files recursively in `config.targetDirectory`.
|
|
17
|
+
* @param config - Configuration for index file generation
|
|
18
|
+
* @throws Error if any step fails.
|
|
19
|
+
*/
|
|
20
|
+
export declare const genIndex: (config: GenIndexConfig) => Promise<void>;
|
|
21
|
+
//# sourceMappingURL=gen-index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gen-index.d.mts","sourceRoot":"","sources":["../../src/functions/gen-index.mts"],"names":[],"mappings":"AACA,OAAO,oBAAoB,CAAC;AAI5B;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,YAAY,CAAC;IACxC,kFAAkF;IAClF,eAAe,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAEnC,iEAAiE;IACjE,eAAe,CAAC,EAAE,IAAI,MAAM,EAAE,CAAC;IAE/B,mEAAmE;IACnE,eAAe,CAAC,EAAE,IAAI,MAAM,EAAE,CAAC;IAE/B,gGAAgG;IAChG,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B,CAAC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,QAAQ,GAAU,QAAQ,cAAc,KAAG,OAAO,CAAC,IAAI,CA4DnE,CAAC"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import micromatch from 'micromatch';
|
|
2
|
+
import '../node-global.mjs';
|
|
3
|
+
import { assertExt } from './assert-ext.mjs';
|
|
4
|
+
import { assertPathExists } from './assert-path-exists.mjs';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Generates index.mts files recursively in `config.targetDirectory`.
|
|
8
|
+
* @param config - Configuration for index file generation
|
|
9
|
+
* @throws Error if any step fails.
|
|
10
|
+
*/
|
|
11
|
+
const genIndex = async (config) => {
|
|
12
|
+
echo('Starting index file generation...\n');
|
|
13
|
+
// Merge config with defaults
|
|
14
|
+
const filledConfig = fillConfig(config);
|
|
15
|
+
// Normalize target directories to array
|
|
16
|
+
const targetDirs = typeof config.targetDirectory === 'string'
|
|
17
|
+
? [config.targetDirectory]
|
|
18
|
+
: config.targetDirectory;
|
|
19
|
+
try {
|
|
20
|
+
// Step 1: Validate file extensions
|
|
21
|
+
echo('1. Validating file extensions...');
|
|
22
|
+
await assertExt({
|
|
23
|
+
directories: [
|
|
24
|
+
{
|
|
25
|
+
path: path.resolve(projectRootPath, './src'),
|
|
26
|
+
extension: '.mts',
|
|
27
|
+
ignorePatterns: ['tsconfig.json', 'globals.d.mts'],
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
path: path.resolve(projectRootPath, './scripts'),
|
|
31
|
+
extension: '.mts',
|
|
32
|
+
ignorePatterns: ['tsconfig.json'],
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
});
|
|
36
|
+
echo('✓ File extensions validated\n');
|
|
37
|
+
// Step 2: Verify target directories exist
|
|
38
|
+
for (const dir of targetDirs) {
|
|
39
|
+
const resolvedDir = path.resolve(dir);
|
|
40
|
+
// eslint-disable-next-line no-await-in-loop
|
|
41
|
+
await assertPathExists(resolvedDir, `Target directory: ${dir}`);
|
|
42
|
+
}
|
|
43
|
+
// Step 3: Generate index files
|
|
44
|
+
echo('2. Generating index files...');
|
|
45
|
+
for (const dir of targetDirs) {
|
|
46
|
+
const resolvedDir = path.resolve(dir);
|
|
47
|
+
// eslint-disable-next-line no-await-in-loop
|
|
48
|
+
await generateIndexFileForDir(resolvedDir, filledConfig);
|
|
49
|
+
}
|
|
50
|
+
echo('✓ Index files generated\n');
|
|
51
|
+
// Step 4: Format generated files
|
|
52
|
+
echo('3. Formatting generated files...');
|
|
53
|
+
const fmtResult = await $('npm run fmt');
|
|
54
|
+
if (fmtResult.type === 'error') {
|
|
55
|
+
throw new Error(`Formatting failed: ${fmtResult.exception.message}`);
|
|
56
|
+
}
|
|
57
|
+
echo('✓ Formatting completed\n');
|
|
58
|
+
echo('✅ Index file generation completed successfully!\n');
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
echo(`❌ Index generation failed: ${String(error)}\n`);
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const fillConfig = (config) => {
|
|
66
|
+
const sourceExtension = config.sourceExtension ?? '.mts';
|
|
67
|
+
const exportExtension = config.exportExtension ?? '.mjs'; // For ESM imports, .mts resolves to .mjs
|
|
68
|
+
return {
|
|
69
|
+
targetDirectory: config.targetDirectory,
|
|
70
|
+
sourceExtension,
|
|
71
|
+
exportExtension,
|
|
72
|
+
excludePatterns: config.excludePatterns ?? [
|
|
73
|
+
`*.d${sourceExtension}`,
|
|
74
|
+
`*.test${sourceExtension}`,
|
|
75
|
+
],
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Generates an index.mts file for the given directory.
|
|
80
|
+
* Recursively calls itself for subdirectories.
|
|
81
|
+
* @param dirPath - The absolute path to the directory to process.
|
|
82
|
+
* @param config - The merged configuration object.
|
|
83
|
+
* @param baseDir - The base directory path for calculating relative paths (optional, defaults to dirPath).
|
|
84
|
+
* @throws Error if directory processing fails.
|
|
85
|
+
*/
|
|
86
|
+
const generateIndexFileForDir = async (dirPath, config, baseDir) => {
|
|
87
|
+
try {
|
|
88
|
+
const actualBaseDir = baseDir ?? dirPath;
|
|
89
|
+
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
90
|
+
const subDirectories = [];
|
|
91
|
+
const filesToExport = [];
|
|
92
|
+
for (const entry of entries) {
|
|
93
|
+
const entryName = entry.name;
|
|
94
|
+
const entryPath = path.join(dirPath, entryName);
|
|
95
|
+
const relativePath = path.relative(actualBaseDir, entryPath);
|
|
96
|
+
if (entry.isDirectory()) {
|
|
97
|
+
subDirectories.push(entryName);
|
|
98
|
+
// Recursively call for subdirectories first
|
|
99
|
+
// eslint-disable-next-line no-await-in-loop
|
|
100
|
+
await generateIndexFileForDir(entryPath, config, actualBaseDir);
|
|
101
|
+
}
|
|
102
|
+
else if (entry.isFile() && shouldExportFile(relativePath, config)) {
|
|
103
|
+
filesToExport.push(entryName);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const indexContent = generateIndexContent(subDirectories, filesToExport, config);
|
|
107
|
+
const indexPath = path.join(dirPath, `index${config.sourceExtension}`);
|
|
108
|
+
await fs.writeFile(indexPath, indexContent);
|
|
109
|
+
echo(`Generated: ${path.relative(process.cwd(), indexPath)}`);
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
throw new Error(`Failed to generate index for directory ${dirPath}: ${String(error)}`);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Determines if a file should be exported in the index file.
|
|
117
|
+
* @param filePath - The relative path to the file from the target directory.
|
|
118
|
+
* @param config - The merged configuration object.
|
|
119
|
+
* @returns True if the file should be exported.
|
|
120
|
+
*/
|
|
121
|
+
const shouldExportFile = (filePath, config) => {
|
|
122
|
+
const fileName = path.basename(filePath);
|
|
123
|
+
// Must have the correct source extension
|
|
124
|
+
if (!fileName.endsWith(config.sourceExtension)) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
// Don't export the index file itself
|
|
128
|
+
if (fileName === `index${config.sourceExtension}`) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
// Check against exclusion patterns
|
|
132
|
+
for (const pattern of config.excludePatterns) {
|
|
133
|
+
if (micromatch.isMatch(filePath, pattern) ||
|
|
134
|
+
micromatch.isMatch(fileName, pattern)) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return true;
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Generates the content for an index file.
|
|
142
|
+
* @param subDirectories - Array of subdirectory names.
|
|
143
|
+
* @param filesToExport - Array of file names to export.
|
|
144
|
+
* @param config - The merged configuration object.
|
|
145
|
+
* @returns The index file content.
|
|
146
|
+
*/
|
|
147
|
+
const generateIndexContent = (subDirectories, filesToExport, config) => {
|
|
148
|
+
const exportStatements = [
|
|
149
|
+
...subDirectories.map((subDir) => `export * from "./${subDir}/index${config.exportExtension}";`),
|
|
150
|
+
...filesToExport.map((file) => {
|
|
151
|
+
const fileNameWithoutExt = path.basename(file, config.sourceExtension);
|
|
152
|
+
return `export * from "./${fileNameWithoutExt}${config.exportExtension}";`;
|
|
153
|
+
}),
|
|
154
|
+
];
|
|
155
|
+
return exportStatements.length === 0
|
|
156
|
+
? 'export {};'
|
|
157
|
+
: exportStatements.join('\n');
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
export { genIndex };
|
|
161
|
+
//# sourceMappingURL=gen-index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gen-index.mjs","sources":["../../src/functions/gen-index.mts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../src/functions/index.mts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { assertExt } from './assert-ext.mjs';
|
|
2
|
+
export { assertPathExists, pathExists } from './assert-path-exists.mjs';
|
|
3
|
+
export { assertRepoIsDirty, repoIsDirty } from './assert-repo-is-dirty.mjs';
|
|
4
|
+
export { $ } from './exec-async.mjs';
|
|
5
|
+
export { formatChanged, formatDiffFrom, formatFiles } from './format.mjs';
|
|
6
|
+
export { genIndex } from './gen-index.mjs';
|
|
7
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="ts-type-forge" />
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.mts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { assertExt } from './functions/assert-ext.mjs';
|
|
2
|
+
export { assertPathExists, pathExists } from './functions/assert-path-exists.mjs';
|
|
3
|
+
export { assertRepoIsDirty, repoIsDirty } from './functions/assert-repo-is-dirty.mjs';
|
|
4
|
+
export { $ } from './functions/exec-async.mjs';
|
|
5
|
+
export { formatChanged, formatDiffFrom, formatFiles } from './functions/format.mjs';
|
|
6
|
+
export { genIndex } from './functions/gen-index.mjs';
|
|
7
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { default as glob_ } from 'fast-glob';
|
|
2
|
+
import * as fs_ from 'node:fs/promises';
|
|
3
|
+
import * as path_ from 'node:path';
|
|
4
|
+
import { $ as $_ } from './functions/exec-async.mjs';
|
|
5
|
+
import { projectRootPath as projectRootPath_ } from './project-root-path.mjs';
|
|
6
|
+
declare global {
|
|
7
|
+
const $: typeof $_;
|
|
8
|
+
const echo: typeof console.log;
|
|
9
|
+
const projectRootPath: typeof projectRootPath_;
|
|
10
|
+
const path: typeof path_;
|
|
11
|
+
const fs: typeof fs_;
|
|
12
|
+
const glob: typeof glob_;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=node-global.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-global.d.mts","sourceRoot":"","sources":["../src/node-global.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAAE,eAAe,IAAI,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAc9E,OAAO,CAAC,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,MAAM,IAAI,EAAE,OAAO,OAAO,CAAC,GAAG,CAAC;IAC/B,MAAM,eAAe,EAAE,OAAO,gBAAgB,CAAC;IAE/C,MAAM,IAAI,EAAE,OAAO,KAAK,CAAC;IACzB,MAAM,EAAE,EAAE,OAAO,GAAG,CAAC;IACrB,MAAM,IAAI,EAAE,OAAO,KAAK,CAAC;CAC1B"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import glob_ from 'fast-glob';
|
|
2
|
+
import * as fs_ from 'node:fs/promises';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { $ } from './functions/exec-async.mjs';
|
|
5
|
+
import { projectRootPath } from './project-root-path.mjs';
|
|
6
|
+
|
|
7
|
+
const globalsDef = {
|
|
8
|
+
$: $,
|
|
9
|
+
echo: console.log,
|
|
10
|
+
projectRootPath: projectRootPath,
|
|
11
|
+
path: path,
|
|
12
|
+
fs: fs_,
|
|
13
|
+
glob: glob_,
|
|
14
|
+
};
|
|
15
|
+
Object.assign(globalThis, globalsDef);
|
|
16
|
+
//# sourceMappingURL=node-global.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-global.mjs","sources":["../src/node-global.mts"],"sourcesContent":[null],"names":["$_","projectRootPath_","path_"],"mappings":";;;;;;AAMA,MAAM,UAAU,GAAG;AACjB,IAAA,CAAC,EAAEA,CAAE;IACL,IAAI,EAAE,OAAO,CAAC,GAAG;AACjB,IAAA,eAAe,EAAEC,eAAgB;AAEjC,IAAA,IAAI,EAAEC,IAAK;AACX,IAAA,EAAE,EAAE,GAAG;AACP,IAAA,IAAI,EAAE,KAAK;CACH;AAEV,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-root-path.d.mts","sourceRoot":"","sources":["../src/project-root-path.mts"],"names":[],"mappings":"AAEA,eAAO,MAAM,eAAe,QAA0C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-root-path.mjs","sources":["../src/project-root-path.mts"],"sourcesContent":[null],"names":[],"mappings":";;AAEa,MAAA,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"include":["."]}
|