@cluerise/tools 5.4.0 → 5.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/configs/.nvmrc +1 -1
- package/dist/scripts/check-heroku-node-version/main.js +227 -228
- package/dist/scripts/create-commit-message/main.js +227 -213
- package/dist/scripts/format-commit-message/main.js +194 -181
- package/dist/scripts/init/main.js +557 -601
- package/dist/scripts/lint/main.js +432 -431
- package/dist/scripts/release/main.js +425 -495
- package/dist/scripts/update-node-versions/main.js +243 -259
- package/dist/scripts/update-xcode-version/main.js +202 -204
- package/package.json +19 -19
|
@@ -1,617 +1,573 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import Path from "node:path";
|
|
1
|
+
import { ZodError, z } from "zod";
|
|
3
2
|
import FileSystem from "node:fs/promises";
|
|
4
3
|
import OS from "node:os";
|
|
4
|
+
import Path from "node:path";
|
|
5
5
|
import Process from "node:process";
|
|
6
|
-
import "@commitlint/load";
|
|
7
6
|
import ChildProcess from "node:child_process";
|
|
7
|
+
import "@commitlint/load";
|
|
8
8
|
import { ESLint } from "eslint";
|
|
9
9
|
import { glob } from "glob";
|
|
10
10
|
import * as Prettier from "prettier";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
class ConsoleStatusLogger {
|
|
48
|
-
#command;
|
|
49
|
-
/**
|
|
50
|
-
* Create a new logger for a specific command.
|
|
51
|
-
*
|
|
52
|
-
* @param command The command name to log.
|
|
53
|
-
*/
|
|
54
|
-
constructor(command) {
|
|
55
|
-
this.#command = command;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Log the beginning of a command with the provided argument.
|
|
59
|
-
*
|
|
60
|
-
* @param argument The argument for the command.
|
|
61
|
-
*
|
|
62
|
-
* @example
|
|
63
|
-
* const logger = new ConsoleStatusLogger('Linting');
|
|
64
|
-
* logger.begin('src/index.ts'); // Logs: "Linting src/index.ts..."
|
|
65
|
-
*/
|
|
66
|
-
begin(argument) {
|
|
67
|
-
console.info(`${this.#command} ${argument}...`);
|
|
68
|
-
}
|
|
69
|
-
static #createResultMessage(exitCode) {
|
|
70
|
-
if (exitCode === null) {
|
|
71
|
-
return "Done";
|
|
72
|
-
}
|
|
73
|
-
return exitCode === 0 ? "OK" : "Failed";
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Log the end of a command with the provided argument and exit code.
|
|
77
|
-
*
|
|
78
|
-
* @param argument The argument for the command.
|
|
79
|
-
* @param exitCode The exit code of the command execution. If null, it indicates completion without an error.
|
|
80
|
-
*
|
|
81
|
-
* @example
|
|
82
|
-
* const logger = new ConsoleStatusLogger('Linting');
|
|
83
|
-
* logger.end('src/index.ts'); // Logs: "Linting src/index.ts... Done"
|
|
84
|
-
* logger.end('src/index.ts', 0); // Logs: "Linting src/index.ts... OK"
|
|
85
|
-
* logger.end('src/index.ts', 1); // Logs: "Linting src/index.ts... Failed"
|
|
86
|
-
*/
|
|
87
|
-
end(argument, exitCode = null) {
|
|
88
|
-
console.info(`${this.#command} ${argument}... ${ConsoleStatusLogger.#createResultMessage(exitCode)}`);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
const gitProviderOrigins = {
|
|
92
|
-
github: "https://github.com"
|
|
11
|
+
//#region src/modules/core/config.ts
|
|
12
|
+
var CoreConfig = class {
|
|
13
|
+
static #packageName = "@cluerise/tools";
|
|
14
|
+
/**
|
|
15
|
+
* Determine if the application is running in production mode.
|
|
16
|
+
*
|
|
17
|
+
* This checks the environment variable `import.meta.env.PROD` to determine the mode.
|
|
18
|
+
*
|
|
19
|
+
* @returns True if running in production mode, otherwise false.
|
|
20
|
+
*/
|
|
21
|
+
static get isProd() {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get the path to package configuration files in production.
|
|
26
|
+
*
|
|
27
|
+
* Used to load configuration from the package when running in production.
|
|
28
|
+
*
|
|
29
|
+
* @returns The path to the configuration files in the package.
|
|
30
|
+
*/
|
|
31
|
+
static get configPackage() {
|
|
32
|
+
return `${this.#packageName}/dist/configs`;
|
|
33
|
+
}
|
|
34
|
+
static get #rootDirectory() {
|
|
35
|
+
return this.isProd ? `./node_modules/${this.#packageName}` : ".";
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get the directory path where configuration files are stored.
|
|
39
|
+
*
|
|
40
|
+
* In production, this points to `dist/configs` in the package; in development, it points to the root directory.
|
|
41
|
+
*
|
|
42
|
+
* @returns The path to the configuration directory.
|
|
43
|
+
*/
|
|
44
|
+
static get configDirectory() {
|
|
45
|
+
return this.isProd ? `${this.#rootDirectory}/dist/configs` : this.#rootDirectory;
|
|
46
|
+
}
|
|
93
47
|
};
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region src/modules/core/console-status-logger.ts
|
|
50
|
+
/**
|
|
51
|
+
* Utility class for logging command status messages to the console.
|
|
52
|
+
*
|
|
53
|
+
* Provides methods to log the start and end of command execution, including the result.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* const logger = new ConsoleStatusLogger('Linting');
|
|
57
|
+
* logger.begin('src/index.ts'); // Logs: "Linting src/index.ts..."
|
|
58
|
+
* // ... command execution ...
|
|
59
|
+
* logger.end('src/index.ts'); // Logs: "Linting src/index.ts... Done"
|
|
60
|
+
* logger.end('src/index.ts', 0); // Logs: "Linting src/index.ts... OK"
|
|
61
|
+
* logger.end('src/index.ts', 1); // Logs: "Linting src/index.ts... Failed"
|
|
62
|
+
*/
|
|
63
|
+
var ConsoleStatusLogger = class ConsoleStatusLogger {
|
|
64
|
+
#command;
|
|
65
|
+
/**
|
|
66
|
+
* Create a new logger for a specific command.
|
|
67
|
+
*
|
|
68
|
+
* @param command The command name to log.
|
|
69
|
+
*/
|
|
70
|
+
constructor(command) {
|
|
71
|
+
this.#command = command;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Log the beginning of a command with the provided argument.
|
|
75
|
+
*
|
|
76
|
+
* @param argument The argument for the command.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* const logger = new ConsoleStatusLogger('Linting');
|
|
80
|
+
* logger.begin('src/index.ts'); // Logs: "Linting src/index.ts..."
|
|
81
|
+
*/
|
|
82
|
+
begin(argument) {
|
|
83
|
+
console.info(`${this.#command} ${argument}...`);
|
|
84
|
+
}
|
|
85
|
+
static #createResultMessage(exitCode) {
|
|
86
|
+
if (exitCode === null) return "Done";
|
|
87
|
+
return exitCode === 0 ? "OK" : "Failed";
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Log the end of a command with the provided argument and exit code.
|
|
91
|
+
*
|
|
92
|
+
* @param argument The argument for the command.
|
|
93
|
+
* @param exitCode The exit code of the command execution. If null, it indicates completion without an error.
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* const logger = new ConsoleStatusLogger('Linting');
|
|
97
|
+
* logger.end('src/index.ts'); // Logs: "Linting src/index.ts... Done"
|
|
98
|
+
* logger.end('src/index.ts', 0); // Logs: "Linting src/index.ts... OK"
|
|
99
|
+
* logger.end('src/index.ts', 1); // Logs: "Linting src/index.ts... Failed"
|
|
100
|
+
*/
|
|
101
|
+
end(argument, exitCode = null) {
|
|
102
|
+
console.info(`${this.#command} ${argument}... ${ConsoleStatusLogger.#createResultMessage(exitCode)}`);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region src/modules/core/package-json/git-provider.ts
|
|
107
|
+
var gitProviderOrigins = { github: "https://github.com" };
|
|
108
|
+
var GitProvider = class {
|
|
109
|
+
static #origins = gitProviderOrigins;
|
|
110
|
+
static #names = Object.keys(this.#origins);
|
|
111
|
+
/**
|
|
112
|
+
* Check if the provided name is a valid Git provider name.
|
|
113
|
+
*
|
|
114
|
+
* @param name The name to check.
|
|
115
|
+
* @returns True if the name is valid, otherwise false.
|
|
116
|
+
*/
|
|
117
|
+
static isValidName(name) {
|
|
118
|
+
return this.#names.includes(name);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get the origin URL for the given Git provider name.
|
|
122
|
+
*
|
|
123
|
+
* @param name The Git provider name.
|
|
124
|
+
* @returns The origin URL.
|
|
125
|
+
*/
|
|
126
|
+
static getOrigin(name) {
|
|
127
|
+
return this.#origins[name];
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
//#endregion
|
|
131
|
+
//#region src/modules/core/package-json/package-json-data.ts
|
|
132
|
+
var enginesSchema = z.object({ node: z.string() });
|
|
133
|
+
var repositoryObjectSchema = z.object({
|
|
134
|
+
type: z.string(),
|
|
135
|
+
url: z.string(),
|
|
136
|
+
directory: z.string().optional()
|
|
123
137
|
});
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
138
|
+
var repositorySchema = z.union([z.string(), repositoryObjectSchema]);
|
|
139
|
+
var packageJsonDataSchema = z.object({
|
|
140
|
+
name: z.string(),
|
|
141
|
+
version: z.string().optional(),
|
|
142
|
+
description: z.string().optional(),
|
|
143
|
+
engines: enginesSchema.optional(),
|
|
144
|
+
repository: repositorySchema.optional()
|
|
131
145
|
});
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
146
|
+
//#endregion
|
|
147
|
+
//#region src/modules/core/package-json/package-json.ts
|
|
148
|
+
var PackageJson = class PackageJson {
|
|
149
|
+
#data;
|
|
150
|
+
constructor(data) {
|
|
151
|
+
this.#data = data;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Load and parse the `package.json` file, returning a `PackageJson` instance.
|
|
155
|
+
*
|
|
156
|
+
* Throws an error if the file is invalid or cannot be parsed.
|
|
157
|
+
*
|
|
158
|
+
* @returns A new `PackageJson` instance with parsed data.
|
|
159
|
+
*/
|
|
160
|
+
static async init() {
|
|
161
|
+
const content = await FileSystem.readFile("package.json", { encoding: "utf8" });
|
|
162
|
+
const data = JsonUtils.parse(content);
|
|
163
|
+
const parseResult = packageJsonDataSchema.safeParse(data);
|
|
164
|
+
if (!parseResult.success) throw new Error("Invalid package.json", { cause: parseResult.error });
|
|
165
|
+
return new PackageJson(data);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Get the package name from `package.json`.
|
|
169
|
+
*
|
|
170
|
+
* @returns The package name.
|
|
171
|
+
*/
|
|
172
|
+
get name() {
|
|
173
|
+
return this.#data.name;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Get the package version from `package.json`.
|
|
177
|
+
*
|
|
178
|
+
* @returns The package version.
|
|
179
|
+
*/
|
|
180
|
+
get version() {
|
|
181
|
+
return this.#data.version;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Get the engines field from `package.json`, if present.
|
|
185
|
+
*
|
|
186
|
+
* @returns The engines object or undefined.
|
|
187
|
+
*/
|
|
188
|
+
get engines() {
|
|
189
|
+
return this.#data.engines;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Set the engines field in `package.json`.
|
|
193
|
+
*
|
|
194
|
+
* @param engines The engines object to set.
|
|
195
|
+
*/
|
|
196
|
+
set engines(engines) {
|
|
197
|
+
this.#data.engines = engines;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Get the repository field from `package.json`, if present.
|
|
201
|
+
*
|
|
202
|
+
* @returns The repository object or string, or undefined.
|
|
203
|
+
*/
|
|
204
|
+
get repository() {
|
|
205
|
+
return this.#data.repository;
|
|
206
|
+
}
|
|
207
|
+
#parseGitRepository(urlString) {
|
|
208
|
+
if (!urlString) return null;
|
|
209
|
+
const urlValue = urlString.includes(":") ? urlString : `https://${urlString}`;
|
|
210
|
+
const url = new URL(urlValue);
|
|
211
|
+
const scheme = url.protocol.slice(0, -1);
|
|
212
|
+
if (GitProvider.isValidName(scheme)) {
|
|
213
|
+
const [owner, repositoryName] = url.pathname.split("/");
|
|
214
|
+
if (!owner || !repositoryName) throw new Error("Unknown owner or repositoryName");
|
|
215
|
+
return {
|
|
216
|
+
origin: GitProvider.getOrigin(scheme),
|
|
217
|
+
owner,
|
|
218
|
+
repositoryName
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
if (scheme === "https") {
|
|
222
|
+
const [, owner, repositoryName] = url.pathname.split("/");
|
|
223
|
+
if (!owner || !repositoryName) throw new Error("Unknown owner or repositoryName");
|
|
224
|
+
return {
|
|
225
|
+
origin: url.origin,
|
|
226
|
+
owner,
|
|
227
|
+
repositoryName: repositoryName.endsWith(".git") ? repositoryName.slice(0, -4) : repositoryName
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
throw new Error("Unsupported repository URL");
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Parse the repository information from `package.json` and return a `GitRepository` object or null.
|
|
234
|
+
*
|
|
235
|
+
* Returns null if no repository is defined or if parsing fails.
|
|
236
|
+
*
|
|
237
|
+
* @returns The parsed `GitRepository`, or null if not available.
|
|
238
|
+
*/
|
|
239
|
+
parseGitRepository() {
|
|
240
|
+
if (!this.repository) return null;
|
|
241
|
+
if (typeof this.repository === "string") return this.#parseGitRepository(this.repository);
|
|
242
|
+
return this.#parseGitRepository(this.repository.url);
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Save the current `package.json` data to disk, formatting it as prettified JSON.
|
|
246
|
+
*/
|
|
247
|
+
async save() {
|
|
248
|
+
const content = JsonUtils.prettify(this.#data) + "\n";
|
|
249
|
+
await FileSystem.writeFile("package.json", content, { encoding: "utf8" });
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
//#endregion
|
|
253
|
+
//#region src/modules/core/run-main.ts
|
|
254
|
+
/**
|
|
255
|
+
* Execute the provided main function and handle any errors that occur.
|
|
256
|
+
*
|
|
257
|
+
* If the main function resolves, the process exits with the returned code.
|
|
258
|
+
* If an error is thrown, it logs the error and exits with code 1.
|
|
259
|
+
*
|
|
260
|
+
* @param main The main function to execute.
|
|
261
|
+
*/
|
|
262
|
+
var runMain = (main) => {
|
|
263
|
+
Promise.resolve().then(() => main(process.argv.slice(2))).then((exitCode) => {
|
|
264
|
+
process.exit(exitCode);
|
|
265
|
+
}).catch((error) => {
|
|
266
|
+
console.error("Error:", error);
|
|
267
|
+
process.exit(1);
|
|
268
|
+
});
|
|
269
|
+
};
|
|
270
|
+
//#endregion
|
|
271
|
+
//#region src/modules/core/utils/file-utils.ts
|
|
272
|
+
var FileUtils = class {
|
|
273
|
+
static async createFile(path, content, options = {}) {
|
|
274
|
+
const absolutePath = Path.resolve(Process.cwd(), path);
|
|
275
|
+
const { trailingNewline = true } = options;
|
|
276
|
+
const fileContent = trailingNewline && !content.endsWith(OS.EOL) ? `${content}${OS.EOL}` : content;
|
|
277
|
+
await FileSystem.mkdir(Path.dirname(absolutePath), { recursive: true });
|
|
278
|
+
return FileSystem.writeFile(absolutePath, fileContent);
|
|
279
|
+
}
|
|
280
|
+
static async copyFile(sourceDirectory, filePath, destinationFilePath, mode) {
|
|
281
|
+
const sourcePath = Path.resolve(sourceDirectory, filePath);
|
|
282
|
+
const destinationPath = Path.resolve(Process.cwd(), destinationFilePath ?? filePath);
|
|
283
|
+
await FileSystem.mkdir(Path.dirname(destinationPath), { recursive: true });
|
|
284
|
+
await FileSystem.copyFile(sourcePath, destinationPath);
|
|
285
|
+
if (mode !== void 0) await FileSystem.chmod(destinationPath, mode);
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
//#endregion
|
|
289
|
+
//#region src/modules/core/utils/json-utils.ts
|
|
290
|
+
var JsonUtils = class {
|
|
291
|
+
static stringify(value) {
|
|
292
|
+
return JSON.stringify(value);
|
|
293
|
+
}
|
|
294
|
+
static prettify(value) {
|
|
295
|
+
return JSON.stringify(value, null, 2);
|
|
296
|
+
}
|
|
297
|
+
static parse(value) {
|
|
298
|
+
return JSON.parse(value);
|
|
299
|
+
}
|
|
257
300
|
};
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
await FileSystem.chmod(destinationPath, mode);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
class JsonUtils {
|
|
277
|
-
static stringify(value) {
|
|
278
|
-
return JSON.stringify(value);
|
|
279
|
-
}
|
|
280
|
-
static prettify(value) {
|
|
281
|
-
return JSON.stringify(value, null, 2);
|
|
282
|
-
}
|
|
283
|
-
static parse(value) {
|
|
284
|
-
return JSON.parse(value);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
const toolNameSchema = z.union([
|
|
288
|
-
z.literal("commitlint"),
|
|
289
|
-
z.literal("editorconfig"),
|
|
290
|
-
z.literal("eslint"),
|
|
291
|
-
z.literal("git"),
|
|
292
|
-
z.literal("lint-staged"),
|
|
293
|
-
z.literal("nvm"),
|
|
294
|
-
z.literal("pnpm"),
|
|
295
|
-
z.literal("prettier"),
|
|
296
|
-
z.literal("release"),
|
|
297
|
-
z.literal("typescript"),
|
|
298
|
-
z.literal("vscode")
|
|
301
|
+
//#endregion
|
|
302
|
+
//#region src/modules/init/tool-name.ts
|
|
303
|
+
var toolNameSchema = z.union([
|
|
304
|
+
z.literal("commitlint"),
|
|
305
|
+
z.literal("editorconfig"),
|
|
306
|
+
z.literal("eslint"),
|
|
307
|
+
z.literal("git"),
|
|
308
|
+
z.literal("lint-staged"),
|
|
309
|
+
z.literal("nvm"),
|
|
310
|
+
z.literal("pnpm"),
|
|
311
|
+
z.literal("prettier"),
|
|
312
|
+
z.literal("release"),
|
|
313
|
+
z.literal("typescript"),
|
|
314
|
+
z.literal("vscode")
|
|
299
315
|
]);
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
316
|
+
//#endregion
|
|
317
|
+
//#region src/modules/init/tool-initializer.ts
|
|
318
|
+
var ToolInitializer = class {
|
|
319
|
+
#configDirectory;
|
|
320
|
+
#configPackage;
|
|
321
|
+
constructor(configDirectory, configPackage) {
|
|
322
|
+
this.#configDirectory = configDirectory;
|
|
323
|
+
this.#configPackage = configPackage;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Get the names of all available tools.
|
|
327
|
+
*
|
|
328
|
+
* @returns An array of tool names.
|
|
329
|
+
*/
|
|
330
|
+
get toolNames() {
|
|
331
|
+
return toolNameSchema.options.map((option) => option.value);
|
|
332
|
+
}
|
|
333
|
+
async #initCommitlint() {
|
|
334
|
+
const configPath = "commitlint.config.ts";
|
|
335
|
+
const configContent = `export { default } from '${this.#configPackage}/${configPath}';\n`;
|
|
336
|
+
await FileUtils.createFile(configPath, configContent);
|
|
337
|
+
}
|
|
338
|
+
async #initEditorConfig() {
|
|
339
|
+
await FileUtils.copyFile(this.#configDirectory, ".editorconfig");
|
|
340
|
+
}
|
|
341
|
+
async #initESLint() {
|
|
342
|
+
const configPath = "eslint.config.js";
|
|
343
|
+
const markdownConfigPath = "eslint-markdown.config.js";
|
|
344
|
+
const configContent = `export { default } from '${this.#configPackage}/${configPath}';\n`;
|
|
345
|
+
const markdownConfigContent = `export { default } from '${this.#configPackage}/${markdownConfigPath}';\n`;
|
|
346
|
+
await FileUtils.createFile(configPath, configContent);
|
|
347
|
+
await FileUtils.createFile(markdownConfigPath, markdownConfigContent);
|
|
348
|
+
}
|
|
349
|
+
async #initGit() {
|
|
350
|
+
const sourceGitignorePath = CoreConfig.isProd ? "_gitignore" : ".gitignore";
|
|
351
|
+
await FileUtils.copyFile(this.#configDirectory, sourceGitignorePath, ".gitignore");
|
|
352
|
+
const gitHookDirectory = "hooks";
|
|
353
|
+
const gitHookPaths = [
|
|
354
|
+
Path.join(gitHookDirectory, "commit-msg"),
|
|
355
|
+
Path.join(gitHookDirectory, "post-commit"),
|
|
356
|
+
Path.join(gitHookDirectory, "pre-commit"),
|
|
357
|
+
Path.join(gitHookDirectory, "prepare-commit-msg")
|
|
358
|
+
];
|
|
359
|
+
await Promise.all(gitHookPaths.map((gitHookPath) => FileUtils.copyFile(this.#configDirectory, gitHookPath, void 0, 493)));
|
|
360
|
+
}
|
|
361
|
+
async #initLintStaged() {
|
|
362
|
+
const configPath = "lint-staged.config.js";
|
|
363
|
+
const configContent = `export { default } from '${this.#configPackage}/${configPath}';\n`;
|
|
364
|
+
await FileUtils.createFile(configPath, configContent);
|
|
365
|
+
}
|
|
366
|
+
async #initNvm() {
|
|
367
|
+
await FileUtils.copyFile(this.#configDirectory, ".nvmrc");
|
|
368
|
+
}
|
|
369
|
+
async #initPnpm() {
|
|
370
|
+
await FileUtils.createFile("pnpm-workspace.yaml", "engineStrict: true\ngitChecks: false\nincludeWorkspaceRoot: true\n\npublicHoistPattern:\n - '@commitlint/cli'\n - eslint\n - lint-staged\n - prettier\n - prettier-plugin-sh\n");
|
|
371
|
+
}
|
|
372
|
+
async #initPrettier() {
|
|
373
|
+
const configPath = "prettier.config.js";
|
|
374
|
+
const configContent = `export { default } from '${this.#configPackage}/${configPath}';\n`;
|
|
375
|
+
await FileUtils.createFile(configPath, configContent);
|
|
376
|
+
await FileUtils.copyFile(this.#configDirectory, ".prettierignore");
|
|
377
|
+
}
|
|
378
|
+
async #getReleaseConfigParams() {
|
|
379
|
+
const defaultConfigParams = {
|
|
380
|
+
host: "<host>",
|
|
381
|
+
owner: "<owner>",
|
|
382
|
+
repository: "<repository>"
|
|
383
|
+
};
|
|
384
|
+
try {
|
|
385
|
+
const repository = (await PackageJson.init()).parseGitRepository();
|
|
386
|
+
if (!repository) return defaultConfigParams;
|
|
387
|
+
const { origin, owner, repositoryName } = repository;
|
|
388
|
+
return {
|
|
389
|
+
host: origin,
|
|
390
|
+
owner,
|
|
391
|
+
repository: repositoryName
|
|
392
|
+
};
|
|
393
|
+
} catch {
|
|
394
|
+
return defaultConfigParams;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
async #initRelease() {
|
|
398
|
+
const configPath = "release.config.js";
|
|
399
|
+
const configParams = await this.#getReleaseConfigParams();
|
|
400
|
+
const configContent = `import { createReleaseConfig } from '${this.#configPackage}/${configPath}';\n\nexport default createReleaseConfig(${JsonUtils.prettify(configParams)});\n`;
|
|
401
|
+
await FileUtils.createFile(configPath, configContent);
|
|
402
|
+
}
|
|
403
|
+
async #initTypeScript() {
|
|
404
|
+
const configPath = "tsconfig.json";
|
|
405
|
+
const configContent = `{
|
|
406
|
+
"extends": "${this.#configDirectory}/${configPath}"\n}
|
|
318
407
|
`;
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
#eslint;
|
|
454
|
-
#eslintFixer = null;
|
|
455
|
-
constructor(options) {
|
|
456
|
-
this.#options = options ?? null;
|
|
457
|
-
this.#eslint = new ESLint({
|
|
458
|
-
overrideConfigFile: options?.configPath
|
|
459
|
-
});
|
|
460
|
-
if (options?.fix) {
|
|
461
|
-
this.#eslintFixer = new ESLint({
|
|
462
|
-
fix: options.fix,
|
|
463
|
-
overrideConfigFile: options?.configPath
|
|
464
|
-
});
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
/**
|
|
468
|
-
* Lint files using `lint-staged` with the provided arguments.
|
|
469
|
-
*
|
|
470
|
-
* @param args An array of arguments to pass to `lint-staged`.
|
|
471
|
-
* @returns The exit status of the `lint-staged` command.
|
|
472
|
-
*/
|
|
473
|
-
static lintStaged(args) {
|
|
474
|
-
const { status } = ChildProcess.spawnSync("lint-staged", args, { stdio: "inherit" });
|
|
475
|
-
return status ?? 0;
|
|
476
|
-
}
|
|
477
|
-
static #preparePrettierLintResult(results) {
|
|
478
|
-
if (results.length === 0) {
|
|
479
|
-
return { status: "success" };
|
|
480
|
-
}
|
|
481
|
-
const title = `Linting with Prettier failed with ${results.length} problem${results.length === 1 ? "" : "s"}
|
|
482
|
-
`;
|
|
483
|
-
let message = "Prettier failed with the following files:\n";
|
|
484
|
-
message += results.map((result) => `- ${result.path}`).join("\n");
|
|
485
|
-
message += OS.EOL;
|
|
486
|
-
return {
|
|
487
|
-
status: "failure",
|
|
488
|
-
title,
|
|
489
|
-
message,
|
|
490
|
-
problemCount: results.length
|
|
491
|
-
};
|
|
492
|
-
}
|
|
493
|
-
async #isIgnoredByPrettier(path) {
|
|
494
|
-
if (path.endsWith(".sh")) {
|
|
495
|
-
return false;
|
|
496
|
-
}
|
|
497
|
-
return this.#eslint.isPathIgnored(path);
|
|
498
|
-
}
|
|
499
|
-
async #prettierLint(patterns) {
|
|
500
|
-
const paths = await glob(patterns, {
|
|
501
|
-
nodir: true,
|
|
502
|
-
ignore: "node_modules/**"
|
|
503
|
-
});
|
|
504
|
-
const results = await Promise.all(
|
|
505
|
-
paths.map(async (path) => {
|
|
506
|
-
const config = await Prettier.resolveConfig(path);
|
|
507
|
-
if (!config) {
|
|
508
|
-
return null;
|
|
509
|
-
}
|
|
510
|
-
if (await this.#isIgnoredByPrettier(path)) {
|
|
511
|
-
return null;
|
|
512
|
-
}
|
|
513
|
-
const contentBuffer = await FileSystem.readFile(path);
|
|
514
|
-
const content = contentBuffer.toString();
|
|
515
|
-
if (this.#options?.fix) {
|
|
516
|
-
const nextContent = await Prettier.format(content, {
|
|
517
|
-
...config,
|
|
518
|
-
filepath: path
|
|
519
|
-
});
|
|
520
|
-
await FileSystem.writeFile(path, nextContent);
|
|
521
|
-
return null;
|
|
522
|
-
}
|
|
523
|
-
const result = await Prettier.check(content, {
|
|
524
|
-
...config,
|
|
525
|
-
filepath: path
|
|
526
|
-
});
|
|
527
|
-
return result ? null : { path };
|
|
528
|
-
})
|
|
529
|
-
);
|
|
530
|
-
return results.filter((result) => result !== null);
|
|
531
|
-
}
|
|
532
|
-
async #prepareESLintLintResult(results) {
|
|
533
|
-
const problemCount = results.reduce(
|
|
534
|
-
(sum, result) => sum + result.errorCount + result.warningCount + (this.#options?.fix ? -(result.fixableErrorCount + result.fixableWarningCount) : 0),
|
|
535
|
-
0
|
|
536
|
-
);
|
|
537
|
-
if (problemCount === 0) {
|
|
538
|
-
return { status: "success" };
|
|
539
|
-
}
|
|
540
|
-
const title = `ESLint failed with ${problemCount} problem${problemCount === 1 ? "" : "s"}`;
|
|
541
|
-
const formatter = await this.#eslint.loadFormatter("stylish");
|
|
542
|
-
const message = await formatter.format(results);
|
|
543
|
-
return {
|
|
544
|
-
status: "failure",
|
|
545
|
-
title,
|
|
546
|
-
message,
|
|
547
|
-
problemCount
|
|
548
|
-
};
|
|
549
|
-
}
|
|
550
|
-
async #eslintLint(patterns) {
|
|
551
|
-
const results = await this.#eslint.lintFiles(patterns);
|
|
552
|
-
const errorResults = ESLint.getErrorResults(results);
|
|
553
|
-
if (this.#eslintFixer && errorResults.length > 0) {
|
|
554
|
-
await ESLint.outputFixes(await this.#eslintFixer.lintFiles(patterns));
|
|
555
|
-
}
|
|
556
|
-
return results;
|
|
557
|
-
}
|
|
558
|
-
/**
|
|
559
|
-
* Lint files matching the provided patterns using ESLint and Prettier.
|
|
560
|
-
*
|
|
561
|
-
* @param patterns An array of glob patterns to match files against. Defaults to ['**'] which matches all files.
|
|
562
|
-
* @returns A promise that resolves to a LintFilesResult indicating the success or failure of the linting process.
|
|
563
|
-
*/
|
|
564
|
-
async lint(patterns = ["**"]) {
|
|
565
|
-
const prettierResults = await this.#prettierLint(patterns);
|
|
566
|
-
const eslintResults = await this.#eslintLint(patterns);
|
|
567
|
-
const eslintResult = await this.#prepareESLintLintResult(eslintResults);
|
|
568
|
-
if (eslintResult.status === "failure") {
|
|
569
|
-
return eslintResult;
|
|
570
|
-
}
|
|
571
|
-
const prettierResult = FileLinter.#preparePrettierLintResult(prettierResults);
|
|
572
|
-
if (prettierResult.status === "failure") {
|
|
573
|
-
return prettierResult;
|
|
574
|
-
}
|
|
575
|
-
return {
|
|
576
|
-
status: "success"
|
|
577
|
-
};
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
const toolNameArgSchema = z.union([z.literal("all"), toolNameSchema]);
|
|
581
|
-
const parseInitArgs = ([nameArg]) => {
|
|
582
|
-
const name = toolNameArgSchema.parse(nameArg);
|
|
583
|
-
return {
|
|
584
|
-
name
|
|
585
|
-
};
|
|
408
|
+
await FileUtils.createFile(configPath, configContent);
|
|
409
|
+
}
|
|
410
|
+
async #initVSCode() {
|
|
411
|
+
const settingsPath = Path.join(".vscode", "settings.json");
|
|
412
|
+
await FileUtils.createFile(settingsPath, "{\n \"editor.codeActionsOnSave\": {\n \"source.fixAll.eslint\": \"explicit\"\n },\n \"typescript.tsdk\": \"node_modules/typescript/lib\",\n \"javascript.preferences.importModuleSpecifier\": \"relative\",\n \"javascript.preferences.importModuleSpecifierEnding\": \"js\",\n \"typescript.preferences.importModuleSpecifier\": \"relative\",\n \"typescript.preferences.importModuleSpecifierEnding\": \"js\",\n \"typescript.preferences.preferTypeOnlyAutoImports\": true\n}\n");
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Initialize the specified tool.
|
|
416
|
+
*
|
|
417
|
+
* @param toolName The name of the tool to initialize.
|
|
418
|
+
* @returns A promise that resolves when the tool is initialized.
|
|
419
|
+
*/
|
|
420
|
+
async initTool(toolName) {
|
|
421
|
+
switch (toolName) {
|
|
422
|
+
case "commitlint": return this.#initCommitlint();
|
|
423
|
+
case "editorconfig": return this.#initEditorConfig();
|
|
424
|
+
case "eslint": return this.#initESLint();
|
|
425
|
+
case "git": return this.#initGit();
|
|
426
|
+
case "lint-staged": return this.#initLintStaged();
|
|
427
|
+
case "nvm": return this.#initNvm();
|
|
428
|
+
case "pnpm": return this.#initPnpm();
|
|
429
|
+
case "prettier": return this.#initPrettier();
|
|
430
|
+
case "release": return this.#initRelease();
|
|
431
|
+
case "typescript": return this.#initTypeScript();
|
|
432
|
+
case "vscode": return this.#initVSCode();
|
|
433
|
+
default: {
|
|
434
|
+
const unhandledToolName = toolName;
|
|
435
|
+
throw new Error(`Unknown tool name: ${unhandledToolName}`);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
};
|
|
440
|
+
//#endregion
|
|
441
|
+
//#region src/modules/lint/file-linter.ts
|
|
442
|
+
var FileLinter = class FileLinter {
|
|
443
|
+
#options;
|
|
444
|
+
#eslint;
|
|
445
|
+
#eslintFixer = null;
|
|
446
|
+
constructor(options) {
|
|
447
|
+
this.#options = options ?? null;
|
|
448
|
+
this.#eslint = new ESLint({ overrideConfigFile: options?.configPath });
|
|
449
|
+
if (options?.fix) this.#eslintFixer = new ESLint({
|
|
450
|
+
fix: options.fix,
|
|
451
|
+
overrideConfigFile: options?.configPath
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Lint files using `lint-staged` with the provided arguments.
|
|
456
|
+
*
|
|
457
|
+
* @param args An array of arguments to pass to `lint-staged`.
|
|
458
|
+
* @returns The exit status of the `lint-staged` command.
|
|
459
|
+
*/
|
|
460
|
+
static lintStaged(args) {
|
|
461
|
+
const { status } = ChildProcess.spawnSync("lint-staged", args, { stdio: "inherit" });
|
|
462
|
+
return status ?? 0;
|
|
463
|
+
}
|
|
464
|
+
static #preparePrettierLintResult(results) {
|
|
465
|
+
if (results.length === 0) return { status: "success" };
|
|
466
|
+
const title = `Linting with Prettier failed with ${results.length} problem${results.length === 1 ? "" : "s"}\n`;
|
|
467
|
+
let message = "Prettier failed with the following files:\n";
|
|
468
|
+
message += results.map((result) => `- ${result.path}`).join("\n");
|
|
469
|
+
message += OS.EOL;
|
|
470
|
+
return {
|
|
471
|
+
status: "failure",
|
|
472
|
+
title,
|
|
473
|
+
message,
|
|
474
|
+
problemCount: results.length
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
async #isIgnoredByPrettier(path) {
|
|
478
|
+
if (path.endsWith(".sh")) return false;
|
|
479
|
+
return this.#eslint.isPathIgnored(path);
|
|
480
|
+
}
|
|
481
|
+
async #prettierLint(patterns) {
|
|
482
|
+
const paths = await glob(patterns, {
|
|
483
|
+
nodir: true,
|
|
484
|
+
ignore: "node_modules/**"
|
|
485
|
+
});
|
|
486
|
+
return (await Promise.all(paths.map(async (path) => {
|
|
487
|
+
const config = await Prettier.resolveConfig(path);
|
|
488
|
+
if (!config) return null;
|
|
489
|
+
if (await this.#isIgnoredByPrettier(path)) return null;
|
|
490
|
+
const content = (await FileSystem.readFile(path)).toString();
|
|
491
|
+
if (this.#options?.fix) {
|
|
492
|
+
const nextContent = await Prettier.format(content, {
|
|
493
|
+
...config,
|
|
494
|
+
filepath: path
|
|
495
|
+
});
|
|
496
|
+
await FileSystem.writeFile(path, nextContent);
|
|
497
|
+
return null;
|
|
498
|
+
}
|
|
499
|
+
return await Prettier.check(content, {
|
|
500
|
+
...config,
|
|
501
|
+
filepath: path
|
|
502
|
+
}) ? null : { path };
|
|
503
|
+
}))).filter((result) => result !== null);
|
|
504
|
+
}
|
|
505
|
+
async #prepareESLintLintResult(results) {
|
|
506
|
+
const problemCount = results.reduce((sum, result) => sum + result.errorCount + result.warningCount + (this.#options?.fix ? -(result.fixableErrorCount + result.fixableWarningCount) : 0), 0);
|
|
507
|
+
if (problemCount === 0) return { status: "success" };
|
|
508
|
+
return {
|
|
509
|
+
status: "failure",
|
|
510
|
+
title: `ESLint failed with ${problemCount} problem${problemCount === 1 ? "" : "s"}`,
|
|
511
|
+
message: await (await this.#eslint.loadFormatter("stylish")).format(results),
|
|
512
|
+
problemCount
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
async #eslintLint(patterns) {
|
|
516
|
+
const results = await this.#eslint.lintFiles(patterns);
|
|
517
|
+
const errorResults = ESLint.getErrorResults(results);
|
|
518
|
+
if (this.#eslintFixer && errorResults.length > 0) await ESLint.outputFixes(await this.#eslintFixer.lintFiles(patterns));
|
|
519
|
+
return results;
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Lint files matching the provided patterns using ESLint and Prettier.
|
|
523
|
+
*
|
|
524
|
+
* @param patterns An array of glob patterns to match files against. Defaults to ['**'] which matches all files.
|
|
525
|
+
* @returns A promise that resolves to a LintFilesResult indicating the success or failure of the linting process.
|
|
526
|
+
*/
|
|
527
|
+
async lint(patterns = ["**"]) {
|
|
528
|
+
const prettierResults = await this.#prettierLint(patterns);
|
|
529
|
+
const eslintResults = await this.#eslintLint(patterns);
|
|
530
|
+
const eslintResult = await this.#prepareESLintLintResult(eslintResults);
|
|
531
|
+
if (eslintResult.status === "failure") return eslintResult;
|
|
532
|
+
const prettierResult = FileLinter.#preparePrettierLintResult(prettierResults);
|
|
533
|
+
if (prettierResult.status === "failure") return prettierResult;
|
|
534
|
+
return { status: "success" };
|
|
535
|
+
}
|
|
536
|
+
};
|
|
537
|
+
//#endregion
|
|
538
|
+
//#region src/app/scripts/init/args.ts
|
|
539
|
+
var toolNameArgSchema = z.union([z.literal("all"), toolNameSchema]);
|
|
540
|
+
var parseInitArgs = ([nameArg]) => {
|
|
541
|
+
return { name: toolNameArgSchema.parse(nameArg) };
|
|
586
542
|
};
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
return 1;
|
|
615
|
-
}
|
|
543
|
+
//#endregion
|
|
544
|
+
//#region src/app/scripts/init/main.ts
|
|
545
|
+
var main = async (args) => {
|
|
546
|
+
try {
|
|
547
|
+
const { name } = parseInitArgs(args);
|
|
548
|
+
const toolInitializer = new ToolInitializer(CoreConfig.configDirectory, CoreConfig.configPackage);
|
|
549
|
+
const fileLinter = new FileLinter({ fix: true });
|
|
550
|
+
const statusLogger = new ConsoleStatusLogger("Initializing");
|
|
551
|
+
const toolNames = name === "all" ? toolInitializer.toolNames : [name];
|
|
552
|
+
for (const toolName of toolNames) {
|
|
553
|
+
statusLogger.begin(toolName);
|
|
554
|
+
await toolInitializer.initTool(toolName);
|
|
555
|
+
statusLogger.end(toolName);
|
|
556
|
+
}
|
|
557
|
+
await fileLinter.lint();
|
|
558
|
+
return 0;
|
|
559
|
+
} catch (error) {
|
|
560
|
+
if (error instanceof ZodError) {
|
|
561
|
+
if (error.issues[0]?.code === "invalid_union") {
|
|
562
|
+
console.error("Error: Invalid tool name");
|
|
563
|
+
return 1;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
if (error instanceof Error) console.error("Error:", error.message);
|
|
567
|
+
else console.error("Error:", error);
|
|
568
|
+
return 1;
|
|
569
|
+
}
|
|
616
570
|
};
|
|
617
571
|
runMain(main);
|
|
572
|
+
//#endregion
|
|
573
|
+
export {};
|