adamantite 0.14.0 → 0.14.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/bin/adamantite +1 -1
- package/dist/index.js +537 -0
- package/package.json +5 -5
- package/dist/index.mjs +0 -395
package/bin/adamantite
CHANGED
package/dist/index.js
ADDED
|
@@ -0,0 +1,537 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import yargs from "yargs";
|
|
3
|
+
import { hideBin } from "yargs/helpers";
|
|
4
|
+
|
|
5
|
+
// src/commands/check.ts
|
|
6
|
+
import process3 from "node:process";
|
|
7
|
+
import { log } from "@clack/prompts";
|
|
8
|
+
import { Fault as Fault3 } from "faultier";
|
|
9
|
+
import { ok as ok3, safeTry as safeTry2 } from "neverthrow";
|
|
10
|
+
import { dlxCommand } from "nypm";
|
|
11
|
+
|
|
12
|
+
// src/helpers/packages/biome.ts
|
|
13
|
+
import { readFile as readFile2, writeFile } from "node:fs/promises";
|
|
14
|
+
import { join as join2 } from "node:path";
|
|
15
|
+
import { Fault as Fault2 } from "faultier";
|
|
16
|
+
import { err as err2, fromPromise as fromPromise2, ok as ok2, safeTry } from "neverthrow";
|
|
17
|
+
|
|
18
|
+
// src/utils.ts
|
|
19
|
+
import { execSync } from "node:child_process";
|
|
20
|
+
import { access, readFile } from "node:fs/promises";
|
|
21
|
+
import { join } from "node:path";
|
|
22
|
+
import process2 from "node:process";
|
|
23
|
+
import defu from "defu";
|
|
24
|
+
import { Fault } from "faultier";
|
|
25
|
+
import { parse } from "jsonc-parser";
|
|
26
|
+
import { err, fromPromise, fromThrowable, ok } from "neverthrow";
|
|
27
|
+
import { detectPackageManager } from "nypm";
|
|
28
|
+
function defineCommand(input) {
|
|
29
|
+
return input;
|
|
30
|
+
}
|
|
31
|
+
var runCommand = fromThrowable(execSync, (error) => Fault.wrap(error).withTag("FAILED_TO_RUN_COMMAND"));
|
|
32
|
+
var getPackageManagerName = () => fromPromise(detectPackageManager(process2.cwd()), () => "Failed to detect package manager").andThen((result) => result ? ok(result.name) : err("Failed to resolve package manager")).mapErr((message) => Fault.create("NO_PACKAGE_MANAGER").withDescription(message, "We're unable to detect the package manager used in this project. Please ensure you have a package.json file in the current directory."));
|
|
33
|
+
var checkIfExists = (path) => fromPromise(access(path), () => new Error("File not found")).match(() => true, () => false);
|
|
34
|
+
var parseJson = (content) => {
|
|
35
|
+
const errors = [];
|
|
36
|
+
const parsed = parse(content, errors);
|
|
37
|
+
if (errors.length > 0) {
|
|
38
|
+
return err(Fault.create("FAILED_TO_PARSE_FILE").withDescription("Failed to parse JSON", "We're unable to parse the provided JSON file.").withContext({ errors }));
|
|
39
|
+
}
|
|
40
|
+
return ok(parsed);
|
|
41
|
+
};
|
|
42
|
+
var mergeConfig = fromThrowable(defu, (error) => Fault.wrap(error).withTag("FAILED_TO_MERGE_CONFIG").withDescription("Failed to merge configuration", "We're unable to merge the configuration files."));
|
|
43
|
+
var readPackageJson = (cwd = process2.cwd()) => fromPromise(readFile(join(cwd, "package.json"), "utf-8"), (error) => Fault.wrap(error).withTag("FAILED_TO_READ_FILE").withDescription("Failed to read package.json", "We're unable to read the package.json file in the current directory.").withContext({ path: join(cwd, "package.json") })).andThen((content) => parseJson(content)).andThen((parsed) => ok(parsed));
|
|
44
|
+
function getTitle() {
|
|
45
|
+
const terminalWidth = process2.stdout.columns || 80;
|
|
46
|
+
if (terminalWidth >= 120) {
|
|
47
|
+
return `
|
|
48
|
+
█████ █████ ███ █████
|
|
49
|
+
░░███ ░░███ ░░░ ░░███
|
|
50
|
+
██████ ███████ ██████ █████████████ ██████ ████████ ███████ ████ ███████ ██████
|
|
51
|
+
░░░░░███ ███░░███ ░░░░░███ ░░███░░███░░███ ░░░░░███ ░░███░░███ ░░░███░ ░░███ ░░░███░ ███░░███
|
|
52
|
+
███████ ░███ ░███ ███████ ░███ ░███ ░███ ███████ ░███ ░███ ░███ ░███ ░███ ░███████
|
|
53
|
+
███░░███ ░███ ░███ ███░░███ ░███ ░███ ░███ ███░░███ ░███ ░███ ░███ ███ ░███ ░███ ███░███░░░
|
|
54
|
+
░░████████░░████████░░████████ █████░███ █████░░████████ ████ █████ ░░█████ █████ ░░█████ ░░██████
|
|
55
|
+
░░░░░░░░ ░░░░░░░░ ░░░░░░░░ ░░░░░ ░░░ ░░░░░ ░░░░░░░░ ░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░░
|
|
56
|
+
`;
|
|
57
|
+
}
|
|
58
|
+
return `
|
|
59
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
60
|
+
┃ ADAMANTITE ┃
|
|
61
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
62
|
+
`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// src/helpers/packages/biome.ts
|
|
66
|
+
var biome = {
|
|
67
|
+
name: "@biomejs/biome",
|
|
68
|
+
version: "2.3.10",
|
|
69
|
+
config: {
|
|
70
|
+
$schema: "./node_modules/@biomejs/biome/configuration_schema.json"
|
|
71
|
+
},
|
|
72
|
+
exists: async () => {
|
|
73
|
+
if (await checkIfExists(join2(process.cwd(), "biome.jsonc"))) {
|
|
74
|
+
return { path: join2(process.cwd(), "biome.jsonc") };
|
|
75
|
+
}
|
|
76
|
+
if (await checkIfExists(join2(process.cwd(), "biome.json"))) {
|
|
77
|
+
return { path: join2(process.cwd(), "biome.json") };
|
|
78
|
+
}
|
|
79
|
+
return { path: null };
|
|
80
|
+
},
|
|
81
|
+
create: () => fromPromise2(writeFile(join2(process.cwd(), "biome.jsonc"), JSON.stringify({ ...biome.config, extends: ["adamantite"] }, null, 2)), (error) => Fault2.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write Biome configuration", "We're unable to write the Biome configuration to the current directory.")),
|
|
82
|
+
update: () => safeTry(async function* () {
|
|
83
|
+
const exists = await biome.exists();
|
|
84
|
+
if (!exists.path) {
|
|
85
|
+
return err2(Fault2.create("FILE_NOT_FOUND").withDescription("No `biome.jsonc` or `biome.json` found", "We're unable to find a Biome configuration in the current directory."));
|
|
86
|
+
}
|
|
87
|
+
const biomeFile = yield* fromPromise2(readFile2(exists.path, "utf-8"), (error) => Fault2.wrap(error).withTag("FAILED_TO_READ_FILE").withDescription("Failed to read Biome configuration", "We're unable to read the Biome configuration from the current directory."));
|
|
88
|
+
const existingConfig = yield* parseJson(biomeFile);
|
|
89
|
+
if (!existingConfig || Object.keys(existingConfig).length === 0) {
|
|
90
|
+
return err2(Fault2.create("INVALID_BIOME_CONFIG").withDescription("Invalid Biome configuration", "The Biome configuration file is empty or invalid.").withContext({ path: exists.path }));
|
|
91
|
+
}
|
|
92
|
+
const newConfig = { ...existingConfig };
|
|
93
|
+
if (!Array.isArray(newConfig.extends)) {
|
|
94
|
+
newConfig.extends = newConfig.extends ? [newConfig.extends] : [];
|
|
95
|
+
}
|
|
96
|
+
if (!newConfig.extends.includes("adamantite")) {
|
|
97
|
+
newConfig.extends.push("adamantite");
|
|
98
|
+
}
|
|
99
|
+
const mergedConfig = yield* mergeConfig(newConfig, biome.config);
|
|
100
|
+
mergedConfig.$schema = biome.config.$schema;
|
|
101
|
+
yield* fromPromise2(writeFile(exists.path, JSON.stringify(mergedConfig, null, 2)), (error) => Fault2.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write Biome configuration", "We're unable to write the Biome configuration to the current directory.").withContext({ path: exists.path }));
|
|
102
|
+
return ok2();
|
|
103
|
+
})
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
// src/commands/check.ts
|
|
107
|
+
var check_default = defineCommand({
|
|
108
|
+
command: "check [files..]",
|
|
109
|
+
describe: "Run Biome linter and check files for issues",
|
|
110
|
+
builder: (yargs) => yargs.positional("files", {
|
|
111
|
+
describe: "Specific files to lint (optional)",
|
|
112
|
+
type: "string",
|
|
113
|
+
array: true
|
|
114
|
+
}).option("summary", {
|
|
115
|
+
type: "boolean",
|
|
116
|
+
description: "Show summary of lint results"
|
|
117
|
+
}),
|
|
118
|
+
handler: async (argv) => safeTry2(async function* () {
|
|
119
|
+
const packageManager = yield* getPackageManagerName();
|
|
120
|
+
const args = ["check"];
|
|
121
|
+
if (argv.summary) {
|
|
122
|
+
args.push("--reporter", "summary");
|
|
123
|
+
}
|
|
124
|
+
if (argv.files && argv.files.length > 0) {
|
|
125
|
+
args.push(...argv.files);
|
|
126
|
+
}
|
|
127
|
+
const command = dlxCommand(packageManager, biome.name, { args });
|
|
128
|
+
yield* runCommand(command, { stdio: "inherit" });
|
|
129
|
+
return ok3(undefined);
|
|
130
|
+
}).match(() => {
|
|
131
|
+
process3.exit(0);
|
|
132
|
+
}, (error) => {
|
|
133
|
+
if (Fault3.isFault(error) && error.tag === "NO_PACKAGE_MANAGER") {
|
|
134
|
+
log.error(error.flatten());
|
|
135
|
+
}
|
|
136
|
+
process3.exit(1);
|
|
137
|
+
})
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// src/commands/ci.ts
|
|
141
|
+
import process4 from "node:process";
|
|
142
|
+
import { log as log2 } from "@clack/prompts";
|
|
143
|
+
import { Fault as Fault4 } from "faultier";
|
|
144
|
+
import { ok as ok4, safeTry as safeTry3 } from "neverthrow";
|
|
145
|
+
import { dlxCommand as dlxCommand2 } from "nypm";
|
|
146
|
+
|
|
147
|
+
// src/helpers/packages/sherif.ts
|
|
148
|
+
var sherif = {
|
|
149
|
+
name: "sherif",
|
|
150
|
+
version: "1.9.0"
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
// src/commands/ci.ts
|
|
154
|
+
var ci_default = defineCommand({
|
|
155
|
+
command: "ci",
|
|
156
|
+
describe: "Run Adamantite in a CI environment",
|
|
157
|
+
builder: (yargs) => yargs.option("monorepo", {
|
|
158
|
+
type: "boolean",
|
|
159
|
+
description: "Run additional monorepo-specific checks"
|
|
160
|
+
}).option("github", {
|
|
161
|
+
type: "boolean",
|
|
162
|
+
description: "Use GitHub reporter"
|
|
163
|
+
}),
|
|
164
|
+
handler: async (argv) => safeTry3(async function* () {
|
|
165
|
+
const packageManager = yield* getPackageManagerName();
|
|
166
|
+
const tools = [
|
|
167
|
+
{
|
|
168
|
+
package: biome.name,
|
|
169
|
+
args: ["ci", ...argv.github ? ["--reporter", "github"] : []]
|
|
170
|
+
}
|
|
171
|
+
];
|
|
172
|
+
if (argv.monorepo) {
|
|
173
|
+
tools.push({ package: sherif.name, args: [] });
|
|
174
|
+
}
|
|
175
|
+
for (const tool of tools) {
|
|
176
|
+
const command = dlxCommand2(packageManager, tool.package, {
|
|
177
|
+
args: tool.args
|
|
178
|
+
});
|
|
179
|
+
yield* runCommand(command, {
|
|
180
|
+
stdio: "inherit"
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
return ok4(undefined);
|
|
184
|
+
}).match(() => {
|
|
185
|
+
process4.exit(0);
|
|
186
|
+
}, (error) => {
|
|
187
|
+
if (Fault4.isFault(error) && error.tag === "NO_PACKAGE_MANAGER") {
|
|
188
|
+
log2.error(error.flatten());
|
|
189
|
+
}
|
|
190
|
+
process4.exit(1);
|
|
191
|
+
})
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// src/commands/fix.ts
|
|
195
|
+
import process5 from "node:process";
|
|
196
|
+
import { log as log3 } from "@clack/prompts";
|
|
197
|
+
import { Fault as Fault5 } from "faultier";
|
|
198
|
+
import { ok as ok5, safeTry as safeTry4 } from "neverthrow";
|
|
199
|
+
import { dlxCommand as dlxCommand3 } from "nypm";
|
|
200
|
+
var fix_default = defineCommand({
|
|
201
|
+
command: "fix [files..]",
|
|
202
|
+
describe: "Run Biome linter and fix issues in files",
|
|
203
|
+
builder: (yargs) => yargs.positional("files", {
|
|
204
|
+
describe: "Specific files to fix (optional)",
|
|
205
|
+
type: "string",
|
|
206
|
+
array: true
|
|
207
|
+
}).option("unsafe", {
|
|
208
|
+
type: "boolean",
|
|
209
|
+
description: "Apply unsafe fixes"
|
|
210
|
+
}),
|
|
211
|
+
handler: async (argv) => safeTry4(async function* () {
|
|
212
|
+
const packageManager = yield* getPackageManagerName();
|
|
213
|
+
const args = ["check", "--write"];
|
|
214
|
+
if (argv.unsafe) {
|
|
215
|
+
args.push("--unsafe");
|
|
216
|
+
}
|
|
217
|
+
if (argv.files && argv.files.length > 0) {
|
|
218
|
+
args.push(...argv.files);
|
|
219
|
+
}
|
|
220
|
+
const command = dlxCommand3(packageManager, biome.name, { args });
|
|
221
|
+
yield* runCommand(command, {
|
|
222
|
+
stdio: "inherit"
|
|
223
|
+
});
|
|
224
|
+
return ok5(undefined);
|
|
225
|
+
}).match(() => {
|
|
226
|
+
process5.exit(0);
|
|
227
|
+
}, (error) => {
|
|
228
|
+
if (Fault5.isFault(error) && error.tag === "NO_PACKAGE_MANAGER") {
|
|
229
|
+
log3.error(error.flatten());
|
|
230
|
+
}
|
|
231
|
+
process5.exit(1);
|
|
232
|
+
})
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
// src/commands/init.ts
|
|
236
|
+
import { writeFile as writeFile4 } from "node:fs/promises";
|
|
237
|
+
import { join as join5 } from "node:path";
|
|
238
|
+
import process6 from "node:process";
|
|
239
|
+
import { cancel, confirm, intro, isCancel, log as log4, multiselect, outro, spinner } from "@clack/prompts";
|
|
240
|
+
import { Fault as Fault8 } from "faultier";
|
|
241
|
+
import { err as err3, fromPromise as fromPromise5, fromSafePromise, ok as ok8, safeTry as safeTry7 } from "neverthrow";
|
|
242
|
+
import { addDevDependency } from "nypm";
|
|
243
|
+
|
|
244
|
+
// src/helpers/editors/vscode.ts
|
|
245
|
+
import { mkdir, readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
|
|
246
|
+
import { join as join3 } from "node:path";
|
|
247
|
+
import { Fault as Fault6 } from "faultier";
|
|
248
|
+
import { fromPromise as fromPromise3, ok as ok6, safeTry as safeTry5 } from "neverthrow";
|
|
249
|
+
var vscode = {
|
|
250
|
+
config: {
|
|
251
|
+
"typescript.tsdk": "node_modules/typescript/lib",
|
|
252
|
+
"editor.formatOnSave": true,
|
|
253
|
+
"editor.formatOnPaste": true,
|
|
254
|
+
"editor.codeActionsOnSave": {
|
|
255
|
+
"source.organizeImports.biome": "explicit",
|
|
256
|
+
"source.fixAll.biome": "explicit"
|
|
257
|
+
},
|
|
258
|
+
"[javascript][typescript][javascriptreact][typescriptreact][json][jsonc][css][graphql]": {
|
|
259
|
+
"editor.defaultFormatter": "biomejs.biome"
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
exists: () => checkIfExists(join3(process.cwd(), ".vscode", "settings.json")),
|
|
263
|
+
create: () => safeTry5(async function* () {
|
|
264
|
+
const vscodePath = join3(process.cwd(), ".vscode");
|
|
265
|
+
yield* fromPromise3(mkdir(vscodePath, { recursive: true }), (error) => Fault6.wrap(error).withTag("FAILED_TO_CREATE_DIRECTORY").withDescription("Failed to create .vscode directory", "We're unable to create the .vscode directory in the current directory.").withContext({ path: vscodePath }));
|
|
266
|
+
yield* fromPromise3(writeFile2(join3(vscodePath, "settings.json"), JSON.stringify(vscode.config, null, 2)), (error) => Fault6.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write .vscode/settings.json", "We're unable to write the .vscode/settings.json file in the current directory."));
|
|
267
|
+
return ok6();
|
|
268
|
+
}),
|
|
269
|
+
update: () => safeTry5(async function* () {
|
|
270
|
+
const vscodePath = join3(process.cwd(), ".vscode", "settings.json");
|
|
271
|
+
const vscodeFile = yield* fromPromise3(readFile3(vscodePath, "utf-8"), (error) => Fault6.wrap(error).withTag("FAILED_TO_READ_FILE").withDescription("Failed to read .vscode/settings.json", "We're unable to read the .vscode/settings.json file in the current directory.").withContext({ path: vscodePath }));
|
|
272
|
+
const existingConfig = yield* parseJson(vscodeFile);
|
|
273
|
+
const newConfig = yield* mergeConfig(vscode.config, existingConfig);
|
|
274
|
+
yield* fromPromise3(writeFile2(join3(process.cwd(), ".vscode", "settings.json"), JSON.stringify(newConfig, null, 2)), (error) => Fault6.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write .vscode/settings.json", "We're unable to write the .vscode/settings.json file in the current directory.").withContext({ path: vscodePath }));
|
|
275
|
+
return ok6();
|
|
276
|
+
})
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
// src/helpers/tsconfig.ts
|
|
280
|
+
import { readFile as readFile4, writeFile as writeFile3 } from "node:fs/promises";
|
|
281
|
+
import { join as join4 } from "node:path";
|
|
282
|
+
import { Fault as Fault7 } from "faultier";
|
|
283
|
+
import { fromPromise as fromPromise4, ok as ok7, safeTry as safeTry6 } from "neverthrow";
|
|
284
|
+
var tsconfig = {
|
|
285
|
+
config: { extends: "adamantite/tsconfig" },
|
|
286
|
+
exists: () => checkIfExists(join4(process.cwd(), "tsconfig.json")),
|
|
287
|
+
create: () => fromPromise4(writeFile3(join4(process.cwd(), "tsconfig.json"), JSON.stringify(tsconfig.config, null, 2)), (error) => Fault7.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write tsconfig.json", "We're unable to write the tsconfig.json file in the current directory.")),
|
|
288
|
+
update: () => safeTry6(async function* () {
|
|
289
|
+
const tsconfigFile = yield* fromPromise4(readFile4(join4(process.cwd(), "tsconfig.json"), "utf-8"), (error) => Fault7.wrap(error).withTag("FAILED_TO_READ_FILE").withDescription("Failed to read tsconfig.json", "We're unable to read the tsconfig.json file in the current directory."));
|
|
290
|
+
const existingConfig = yield* parseJson(tsconfigFile);
|
|
291
|
+
const newConfig = yield* mergeConfig(tsconfig.config, existingConfig);
|
|
292
|
+
yield* fromPromise4(writeFile3(join4(process.cwd(), "tsconfig.json"), JSON.stringify(newConfig, null, 2)), (error) => Fault7.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write tsconfig.json", "We're unable to write the tsconfig.json file in the current directory."));
|
|
293
|
+
return ok7();
|
|
294
|
+
})
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
// src/commands/init.ts
|
|
298
|
+
var init_default = defineCommand({
|
|
299
|
+
command: "init",
|
|
300
|
+
describe: "Initialize Adamantite in the current directory",
|
|
301
|
+
builder: (yargs) => yargs,
|
|
302
|
+
handler: async () => {
|
|
303
|
+
const cwd = process6.cwd();
|
|
304
|
+
return safeTry7(async function* () {
|
|
305
|
+
let packageJson = yield* readPackageJson();
|
|
306
|
+
intro(getTitle());
|
|
307
|
+
const hasPnpmWorkspace = await checkIfExists(join5(process6.cwd(), "pnpm-workspace.yaml"));
|
|
308
|
+
const isMonorepo = packageJson.workspaces !== undefined || hasPnpmWorkspace;
|
|
309
|
+
const shouldInstallScripts = yield* fromSafePromise(confirm({
|
|
310
|
+
message: "Do you want to add the `check` and `fix` scripts to your `package.json`?"
|
|
311
|
+
}));
|
|
312
|
+
if (isCancel(shouldInstallScripts)) {
|
|
313
|
+
return err3(Fault8.create("OPERATION_CANCELLED"));
|
|
314
|
+
}
|
|
315
|
+
let shouldInstallMonorepoScripts = false;
|
|
316
|
+
if (isMonorepo) {
|
|
317
|
+
const shouldInstallMonorepoScriptsResponse = yield* fromSafePromise(confirm({
|
|
318
|
+
message: "We've detected a monorepo setup in your project. Would you like to install monorepo linting scripts?"
|
|
319
|
+
}));
|
|
320
|
+
if (isCancel(shouldInstallMonorepoScriptsResponse)) {
|
|
321
|
+
return err3(Fault8.create("OPERATION_CANCELLED"));
|
|
322
|
+
}
|
|
323
|
+
shouldInstallMonorepoScripts = shouldInstallMonorepoScriptsResponse;
|
|
324
|
+
}
|
|
325
|
+
const shouldInstallTypeScriptPreset = yield* fromSafePromise(confirm({
|
|
326
|
+
message: "Adamantite provides a TypeScript preset to enforce strict type-safety. Would you like to install it?"
|
|
327
|
+
}));
|
|
328
|
+
if (isCancel(shouldInstallTypeScriptPreset)) {
|
|
329
|
+
return err3(Fault8.create("OPERATION_CANCELLED"));
|
|
330
|
+
}
|
|
331
|
+
const selectedEditors = yield* fromSafePromise(multiselect({
|
|
332
|
+
message: "Which editors do you want to configure (recommended)?",
|
|
333
|
+
options: [
|
|
334
|
+
{ label: "VSCode / Cursor / Windsurf", value: "vscode" },
|
|
335
|
+
{ label: "Zed (coming soon)", value: "zed" }
|
|
336
|
+
],
|
|
337
|
+
required: false
|
|
338
|
+
}));
|
|
339
|
+
if (isCancel(selectedEditors)) {
|
|
340
|
+
return err3(Fault8.create("OPERATION_CANCELLED"));
|
|
341
|
+
}
|
|
342
|
+
const installingDependencies = spinner();
|
|
343
|
+
installingDependencies.start("Installing dependencies...");
|
|
344
|
+
yield* fromPromise5(addDevDependency("adamantite"), (error) => Fault8.wrap(error).withTag("FAILED_TO_INSTALL_DEPENDENCY").withMessage("Failed to install Adamantite"));
|
|
345
|
+
yield* fromPromise5(addDevDependency(`${biome.name}@${biome.version}`), (error) => Fault8.wrap(error).withTag("FAILED_TO_INSTALL_DEPENDENCY").withMessage("Failed to install Biome"));
|
|
346
|
+
if (shouldInstallMonorepoScripts) {
|
|
347
|
+
yield* fromPromise5(addDevDependency(`${sherif.name}@${sherif.version}`), (error) => Fault8.wrap(error).withTag("FAILED_TO_INSTALL_DEPENDENCY").withMessage("Failed to install Sherif"));
|
|
348
|
+
}
|
|
349
|
+
installingDependencies.stop("Dependencies installed successfully");
|
|
350
|
+
const settingUpBiomeConfig = spinner();
|
|
351
|
+
settingUpBiomeConfig.start("Setting up Biome config...");
|
|
352
|
+
const biomePath = await biome.exists();
|
|
353
|
+
if (biomePath.path) {
|
|
354
|
+
settingUpBiomeConfig.message("Biome config found, updating...");
|
|
355
|
+
yield* biome.update();
|
|
356
|
+
settingUpBiomeConfig.stop("Biome config updated successfully");
|
|
357
|
+
} else {
|
|
358
|
+
settingUpBiomeConfig.message("Biome config not found, creating...");
|
|
359
|
+
yield* biome.create();
|
|
360
|
+
settingUpBiomeConfig.stop("Biome config created successfully");
|
|
361
|
+
}
|
|
362
|
+
if (shouldInstallScripts) {
|
|
363
|
+
const addingScripts = spinner();
|
|
364
|
+
packageJson = yield* readPackageJson();
|
|
365
|
+
addingScripts.start("Adding scripts to your `package.json`...");
|
|
366
|
+
if (!packageJson.scripts) {
|
|
367
|
+
packageJson.scripts = {};
|
|
368
|
+
}
|
|
369
|
+
packageJson.scripts.check = "adamantite check";
|
|
370
|
+
packageJson.scripts.fix = "adamantite fix";
|
|
371
|
+
if (shouldInstallMonorepoScripts) {
|
|
372
|
+
packageJson.scripts["lint:monorepo"] = "adamantite monorepo";
|
|
373
|
+
}
|
|
374
|
+
yield* fromPromise5(writeFile4(join5(cwd, "package.json"), JSON.stringify(packageJson, null, 2)), (error) => Fault8.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write package.json", "We're unable to update the package.json file.").withContext({ path: join5(cwd, "package.json") }));
|
|
375
|
+
addingScripts.stop("Scripts added to your `package.json`");
|
|
376
|
+
}
|
|
377
|
+
if (shouldInstallTypeScriptPreset) {
|
|
378
|
+
const settingUpTypeScriptConfig = spinner();
|
|
379
|
+
settingUpTypeScriptConfig.start("Setting up TypeScript config...");
|
|
380
|
+
if (await tsconfig.exists()) {
|
|
381
|
+
settingUpTypeScriptConfig.message("`tsconfig.json` found, updating...");
|
|
382
|
+
yield* tsconfig.update();
|
|
383
|
+
settingUpTypeScriptConfig.stop("`tsconfig.json` updated successfully");
|
|
384
|
+
} else {
|
|
385
|
+
settingUpTypeScriptConfig.message("`tsconfig.json` not found, creating...");
|
|
386
|
+
yield* tsconfig.create();
|
|
387
|
+
settingUpTypeScriptConfig.stop("`tsconfig.json` created successfully");
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
if (selectedEditors.length > 0) {
|
|
391
|
+
const settingUpEditorConfig = spinner();
|
|
392
|
+
settingUpEditorConfig.start("Setting up editor config...");
|
|
393
|
+
if (selectedEditors.includes("vscode")) {
|
|
394
|
+
const settingUpVSCodeConfig = spinner();
|
|
395
|
+
settingUpVSCodeConfig.start("Setting up VSCode config...");
|
|
396
|
+
if (await vscode.exists()) {
|
|
397
|
+
settingUpVSCodeConfig.message("VSCode settings found, updating...");
|
|
398
|
+
yield* vscode.update();
|
|
399
|
+
settingUpVSCodeConfig.stop("VSCode settings updated with Adamantite preset");
|
|
400
|
+
} else {
|
|
401
|
+
settingUpVSCodeConfig.message("VSCode settings not found, creating...");
|
|
402
|
+
yield* vscode.create();
|
|
403
|
+
settingUpVSCodeConfig.stop("VSCode settings created with Adamantite preset");
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
if (selectedEditors.includes("zed")) {
|
|
407
|
+
log4.warning("Zed configuration coming soon...");
|
|
408
|
+
}
|
|
409
|
+
settingUpEditorConfig.stop("Editor config set up successfully");
|
|
410
|
+
}
|
|
411
|
+
return ok8();
|
|
412
|
+
}).match(() => {
|
|
413
|
+
outro("\uD83D\uDCA0 Adamantite initialized successfully!");
|
|
414
|
+
process6.exit(0);
|
|
415
|
+
}, (error) => {
|
|
416
|
+
if (Fault8.isFault(error) && error.tag === "OPERATION_CANCELLED") {
|
|
417
|
+
cancel("You've cancelled the initialization process.");
|
|
418
|
+
process6.exit(0);
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
if (Fault8.isFault(error)) {
|
|
422
|
+
log4.error(error.flatten());
|
|
423
|
+
} else {
|
|
424
|
+
log4.error(String(error));
|
|
425
|
+
}
|
|
426
|
+
cancel("Failed to initialize Adamantite");
|
|
427
|
+
process6.exit(1);
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
// src/commands/monorepo.ts
|
|
433
|
+
import process7 from "node:process";
|
|
434
|
+
import { log as log5 } from "@clack/prompts";
|
|
435
|
+
import { Fault as Fault9 } from "faultier";
|
|
436
|
+
import { ok as ok9, safeTry as safeTry8 } from "neverthrow";
|
|
437
|
+
import { dlxCommand as dlxCommand4 } from "nypm";
|
|
438
|
+
var monorepo_default = defineCommand({
|
|
439
|
+
command: "monorepo",
|
|
440
|
+
describe: "Lint and automatically fix monorepo-specific issues using Sherif",
|
|
441
|
+
builder: (yargs) => yargs,
|
|
442
|
+
handler: async () => safeTry8(async function* () {
|
|
443
|
+
const packageManager = yield* getPackageManagerName();
|
|
444
|
+
const args = ["--fix"];
|
|
445
|
+
const command = dlxCommand4(packageManager, sherif.name, { args });
|
|
446
|
+
yield* runCommand(command, {
|
|
447
|
+
stdio: "inherit"
|
|
448
|
+
});
|
|
449
|
+
return ok9(undefined);
|
|
450
|
+
}).match(() => {
|
|
451
|
+
process7.exit(0);
|
|
452
|
+
}, (error) => {
|
|
453
|
+
if (Fault9.isFault(error) && error.tag === "NO_PACKAGE_MANAGER") {
|
|
454
|
+
log5.error(error.flatten());
|
|
455
|
+
}
|
|
456
|
+
process7.exit(1);
|
|
457
|
+
})
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
// src/commands/update.ts
|
|
461
|
+
import process8 from "node:process";
|
|
462
|
+
import { cancel as cancel2, confirm as confirm2, intro as intro2, isCancel as isCancel2, log as log6, outro as outro2, spinner as spinner2 } from "@clack/prompts";
|
|
463
|
+
import { Fault as Fault10 } from "faultier";
|
|
464
|
+
import { err as err4, fromPromise as fromPromise6, fromSafePromise as fromSafePromise2, ok as ok10, safeTry as safeTry9 } from "neverthrow";
|
|
465
|
+
import { addDevDependency as addDevDependency2 } from "nypm";
|
|
466
|
+
var update_default = defineCommand({
|
|
467
|
+
command: "update",
|
|
468
|
+
describe: "Update adamantite dependencies to latest compatible versions",
|
|
469
|
+
builder: (yargs) => yargs,
|
|
470
|
+
handler: async () => safeTry9(async function* () {
|
|
471
|
+
const packageJson = yield* readPackageJson();
|
|
472
|
+
intro2(getTitle());
|
|
473
|
+
const updates = [];
|
|
474
|
+
for (const pkg of [biome, sherif]) {
|
|
475
|
+
const dependency = packageJson.devDependencies?.[pkg.name];
|
|
476
|
+
if (dependency && dependency !== pkg.version) {
|
|
477
|
+
updates.push({
|
|
478
|
+
name: pkg.name,
|
|
479
|
+
currentVersion: dependency,
|
|
480
|
+
targetVersion: pkg.version,
|
|
481
|
+
isDevDependency: true
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
if (updates.length === 0) {
|
|
486
|
+
log6.success("All adamantite dependencies are already up to date!");
|
|
487
|
+
return ok10("no-updates");
|
|
488
|
+
}
|
|
489
|
+
log6.message("The following dependencies will be updated:");
|
|
490
|
+
log6.message("");
|
|
491
|
+
for (const dep of updates) {
|
|
492
|
+
log6.message(` ${dep.name}: ${dep.currentVersion} → ${dep.targetVersion}`);
|
|
493
|
+
}
|
|
494
|
+
log6.message("");
|
|
495
|
+
const shouldUpdate = yield* fromSafePromise2(confirm2({
|
|
496
|
+
message: "Do you want to proceed with these updates?"
|
|
497
|
+
}));
|
|
498
|
+
if (isCancel2(shouldUpdate)) {
|
|
499
|
+
return err4(Fault10.create("OPERATION_CANCELLED"));
|
|
500
|
+
}
|
|
501
|
+
if (!shouldUpdate) {
|
|
502
|
+
return ok10("cancelled");
|
|
503
|
+
}
|
|
504
|
+
const s = spinner2();
|
|
505
|
+
s.start("Updating dependencies...");
|
|
506
|
+
for (const dep of updates) {
|
|
507
|
+
yield* fromPromise6(addDevDependency2(`${dep.name}@${dep.targetVersion}`), (error) => Fault10.wrap(error).withTag("FAILED_TO_INSTALL_DEPENDENCY").withMessage(`Failed to update ${dep.name}`));
|
|
508
|
+
}
|
|
509
|
+
s.stop("Dependencies updated successfully");
|
|
510
|
+
return ok10("updated");
|
|
511
|
+
}).match((value) => {
|
|
512
|
+
if (value === "no-updates") {
|
|
513
|
+
outro2("\uD83D\uDCA0 No updates needed");
|
|
514
|
+
} else if (value === "cancelled") {
|
|
515
|
+
outro2("\uD83D\uDCA0 Update cancelled");
|
|
516
|
+
} else if (value === "updated") {
|
|
517
|
+
outro2("\uD83D\uDCA0 Dependencies updated successfully!");
|
|
518
|
+
}
|
|
519
|
+
process8.exit(0);
|
|
520
|
+
}, (error) => {
|
|
521
|
+
if (Fault10.isFault(error) && error.tag === "OPERATION_CANCELLED") {
|
|
522
|
+
cancel2("You've cancelled the update process.");
|
|
523
|
+
process8.exit(0);
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
if (Fault10.isFault(error)) {
|
|
527
|
+
log6.error(error.flatten());
|
|
528
|
+
} else {
|
|
529
|
+
log6.error(String(error));
|
|
530
|
+
}
|
|
531
|
+
cancel2("Failed to update dependencies");
|
|
532
|
+
process8.exit(1);
|
|
533
|
+
})
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
// src/index.ts
|
|
537
|
+
yargs(hideBin(process.argv)).scriptName("adamantite").version("0.14.2").command(check_default).command(ci_default).command(fix_default).command(init_default).command(monorepo_default).command(update_default).demandCommand(1).strict().help().parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adamantite",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.2",
|
|
4
4
|
"description": "An strict and opinionated set of presets for modern TypeScript applications",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"adamantite",
|
|
@@ -40,10 +40,10 @@
|
|
|
40
40
|
"presets"
|
|
41
41
|
],
|
|
42
42
|
"scripts": {
|
|
43
|
-
"build": "
|
|
43
|
+
"build": "bunup",
|
|
44
44
|
"bump:deps": "bun update --interactive",
|
|
45
45
|
"check": "bun --bun run src/index.ts check",
|
|
46
|
-
"dev": "
|
|
46
|
+
"dev": "bunup --watch",
|
|
47
47
|
"fix": "bun --bun run src/index.ts fix",
|
|
48
48
|
"release": "changeset publish",
|
|
49
49
|
"test": "bun test",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@clack/prompts": "0.11.0",
|
|
56
56
|
"defu": "6.1.4",
|
|
57
|
-
"faultier": "^1.0.
|
|
57
|
+
"faultier": "^1.0.4",
|
|
58
58
|
"jsonc-parser": "3.3.1",
|
|
59
59
|
"neverthrow": "8.2.0",
|
|
60
60
|
"nypm": "0.6.2",
|
|
@@ -65,8 +65,8 @@
|
|
|
65
65
|
"@changesets/cli": "2.29.8",
|
|
66
66
|
"@types/bun": "1.3.5",
|
|
67
67
|
"@types/yargs": "17.0.35",
|
|
68
|
+
"bunup": "0.16.11",
|
|
68
69
|
"sherif": "1.9.0",
|
|
69
|
-
"tsdown": "0.18.1",
|
|
70
70
|
"type-fest": "5.3.1",
|
|
71
71
|
"typescript": "5.9.3"
|
|
72
72
|
},
|
package/dist/index.mjs
DELETED
|
@@ -1,395 +0,0 @@
|
|
|
1
|
-
import yargs from "yargs";
|
|
2
|
-
import { hideBin } from "yargs/helpers";
|
|
3
|
-
import process$1 from "process";
|
|
4
|
-
import { err, fromPromise, fromSafePromise, fromThrowable, ok, safeTry } from "neverthrow";
|
|
5
|
-
import { addDevDependency, detectPackageManager, dlxCommand } from "nypm";
|
|
6
|
-
import { access, mkdir, readFile, writeFile } from "fs/promises";
|
|
7
|
-
import { join } from "path";
|
|
8
|
-
import { Fault } from "faultier";
|
|
9
|
-
import { execSync } from "child_process";
|
|
10
|
-
import defu from "defu";
|
|
11
|
-
import { parse } from "jsonc-parser";
|
|
12
|
-
import { cancel, confirm, intro, isCancel, log, multiselect, outro, spinner } from "@clack/prompts";
|
|
13
|
-
import { readFileSync } from "fs";
|
|
14
|
-
|
|
15
|
-
//#region src/utils.ts
|
|
16
|
-
function defineCommand(input) {
|
|
17
|
-
return input;
|
|
18
|
-
}
|
|
19
|
-
const runCommand = fromThrowable(execSync, (error) => Fault.wrap(error).withTag("FAILED_TO_RUN_COMMAND"));
|
|
20
|
-
const getPackageManagerName = () => fromPromise(detectPackageManager(process$1.cwd()), () => Fault.create("NO_PACKAGE_MANAGER").withDescription("Error while detecting the package manager.", "We're unable to detect the package manager used in this project.")).andThen((result) => {
|
|
21
|
-
if (!result) return err(Fault.create("NO_PACKAGE_MANAGER").withDescription("No package manager detected.", "We're unable to detect the package manager used in this project."));
|
|
22
|
-
return ok(result.name);
|
|
23
|
-
});
|
|
24
|
-
const checkIfExists = (path) => fromPromise(access(path), () => /* @__PURE__ */ new Error("File not found")).match(() => true, () => false);
|
|
25
|
-
const parseJson = (content) => {
|
|
26
|
-
const errors = [];
|
|
27
|
-
const parsed = parse(content, errors);
|
|
28
|
-
if (errors.length > 0) return err(Fault.create("FAILED_TO_PARSE_FILE").withDescription("Failed to parse JSON", "We're unable to parse the provided JSON file.").withContext({ errors }));
|
|
29
|
-
return ok(parsed);
|
|
30
|
-
};
|
|
31
|
-
const mergeConfig = fromThrowable(defu, (error) => Fault.wrap(error).withTag("FAILED_TO_MERGE_CONFIG").withDescription("Failed to merge configuration", "We're unable to merge the configuration files."));
|
|
32
|
-
const readPackageJson = (cwd = process$1.cwd()) => fromPromise(readFile(join(cwd, "package.json"), "utf-8"), (error) => Fault.wrap(error).withTag("FAILED_TO_READ_FILE").withDescription("Failed to read package.json", "We're unable to read the package.json file in the current directory.").withContext({ path: join(cwd, "package.json") })).andThen((content) => parseJson(content)).andThen((parsed) => ok(parsed));
|
|
33
|
-
function getTitle() {
|
|
34
|
-
if ((process$1.stdout.columns || 80) >= 120) return `
|
|
35
|
-
█████ █████ ███ █████
|
|
36
|
-
░░███ ░░███ ░░░ ░░███
|
|
37
|
-
██████ ███████ ██████ █████████████ ██████ ████████ ███████ ████ ███████ ██████
|
|
38
|
-
░░░░░███ ███░░███ ░░░░░███ ░░███░░███░░███ ░░░░░███ ░░███░░███ ░░░███░ ░░███ ░░░███░ ███░░███
|
|
39
|
-
███████ ░███ ░███ ███████ ░███ ░███ ░███ ███████ ░███ ░███ ░███ ░███ ░███ ░███████
|
|
40
|
-
███░░███ ░███ ░███ ███░░███ ░███ ░███ ░███ ███░░███ ░███ ░███ ░███ ███ ░███ ░███ ███░███░░░
|
|
41
|
-
░░████████░░████████░░████████ █████░███ █████░░████████ ████ █████ ░░█████ █████ ░░█████ ░░██████
|
|
42
|
-
░░░░░░░░ ░░░░░░░░ ░░░░░░░░ ░░░░░ ░░░ ░░░░░ ░░░░░░░░ ░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░░
|
|
43
|
-
`;
|
|
44
|
-
return `
|
|
45
|
-
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
46
|
-
┃ ADAMANTITE ┃
|
|
47
|
-
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
48
|
-
`;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
//#endregion
|
|
52
|
-
//#region src/helpers/packages/biome.ts
|
|
53
|
-
const biome = {
|
|
54
|
-
name: "@biomejs/biome",
|
|
55
|
-
version: "2.3.10",
|
|
56
|
-
config: { $schema: "./node_modules/@biomejs/biome/configuration_schema.json" },
|
|
57
|
-
exists: async () => {
|
|
58
|
-
if (await checkIfExists(join(process.cwd(), "biome.jsonc"))) return { path: join(process.cwd(), "biome.jsonc") };
|
|
59
|
-
if (await checkIfExists(join(process.cwd(), "biome.json"))) return { path: join(process.cwd(), "biome.json") };
|
|
60
|
-
return { path: null };
|
|
61
|
-
},
|
|
62
|
-
create: () => fromPromise(writeFile(join(process.cwd(), "biome.jsonc"), JSON.stringify({
|
|
63
|
-
...biome.config,
|
|
64
|
-
extends: ["adamantite"]
|
|
65
|
-
}, null, 2)), (error) => Fault.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write Biome configuration", "We're unable to write the Biome configuration to the current directory.")),
|
|
66
|
-
update: () => safeTry(async function* () {
|
|
67
|
-
const exists = await biome.exists();
|
|
68
|
-
if (!exists.path) return err(Fault.create("FILE_NOT_FOUND").withDescription("No `biome.jsonc` or `biome.json` found", "We're unable to find a Biome configuration in the current directory."));
|
|
69
|
-
const existingConfig = yield* parseJson(yield* fromPromise(readFile(exists.path, "utf-8"), (error) => Fault.wrap(error).withTag("FAILED_TO_READ_FILE").withDescription("Failed to read Biome configuration", "We're unable to read the Biome configuration from the current directory.")));
|
|
70
|
-
if (!existingConfig || Object.keys(existingConfig).length === 0) return err(Fault.create("INVALID_BIOME_CONFIG").withDescription("Invalid Biome configuration", "The Biome configuration file is empty or invalid.").withContext({ path: exists.path }));
|
|
71
|
-
const newConfig = { ...existingConfig };
|
|
72
|
-
if (!Array.isArray(newConfig.extends)) newConfig.extends = newConfig.extends ? [newConfig.extends] : [];
|
|
73
|
-
if (!newConfig.extends.includes("adamantite")) newConfig.extends.push("adamantite");
|
|
74
|
-
const mergedConfig = yield* mergeConfig(newConfig, biome.config);
|
|
75
|
-
mergedConfig.$schema = biome.config.$schema;
|
|
76
|
-
yield* fromPromise(writeFile(exists.path, JSON.stringify(mergedConfig, null, 2)), (error) => Fault.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write Biome configuration", "We're unable to write the Biome configuration to the current directory.").withContext({ path: exists.path }));
|
|
77
|
-
return ok();
|
|
78
|
-
})
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
//#endregion
|
|
82
|
-
//#region src/commands/check.ts
|
|
83
|
-
var check_default = defineCommand({
|
|
84
|
-
command: "check [files..]",
|
|
85
|
-
describe: "Run Biome linter and check files for issues",
|
|
86
|
-
builder: (yargs$1) => yargs$1.positional("files", {
|
|
87
|
-
describe: "Specific files to lint (optional)",
|
|
88
|
-
type: "string",
|
|
89
|
-
array: true
|
|
90
|
-
}).option("summary", {
|
|
91
|
-
type: "boolean",
|
|
92
|
-
description: "Show summary of lint results"
|
|
93
|
-
}),
|
|
94
|
-
handler: async (argv) => {
|
|
95
|
-
if ((await safeTry(async function* () {
|
|
96
|
-
const packageManager = yield* getPackageManagerName();
|
|
97
|
-
const args = ["check"];
|
|
98
|
-
if (argv.summary) args.push("--reporter", "summary");
|
|
99
|
-
if (argv.files && argv.files.length > 0) args.push(...argv.files);
|
|
100
|
-
yield* runCommand(dlxCommand(packageManager, biome.name, { args }), { stdio: "inherit" });
|
|
101
|
-
return ok(void 0);
|
|
102
|
-
})).isOk()) return;
|
|
103
|
-
process$1.exit(1);
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
//#endregion
|
|
108
|
-
//#region src/helpers/packages/sherif.ts
|
|
109
|
-
const sherif = {
|
|
110
|
-
name: "sherif",
|
|
111
|
-
version: "1.9.0"
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
//#endregion
|
|
115
|
-
//#region src/commands/ci.ts
|
|
116
|
-
var ci_default = defineCommand({
|
|
117
|
-
command: "ci",
|
|
118
|
-
describe: "Run Adamantite in a CI environment",
|
|
119
|
-
builder: (yargs$1) => yargs$1.option("monorepo", {
|
|
120
|
-
type: "boolean",
|
|
121
|
-
description: "Run additional monorepo-specific checks"
|
|
122
|
-
}).option("github", {
|
|
123
|
-
type: "boolean",
|
|
124
|
-
description: "Use GitHub reporter"
|
|
125
|
-
}),
|
|
126
|
-
handler: async (argv) => {
|
|
127
|
-
if ((await safeTry(async function* () {
|
|
128
|
-
const packageManager = yield* getPackageManagerName();
|
|
129
|
-
const tools = [{
|
|
130
|
-
package: biome.name,
|
|
131
|
-
args: ["ci", ...argv.github ? ["--reporter", "github"] : []]
|
|
132
|
-
}];
|
|
133
|
-
if (argv.monorepo) tools.push({
|
|
134
|
-
package: sherif.name,
|
|
135
|
-
args: []
|
|
136
|
-
});
|
|
137
|
-
for (const tool of tools) yield* runCommand(dlxCommand(packageManager, tool.package, { args: tool.args }), { stdio: "inherit" });
|
|
138
|
-
return ok(void 0);
|
|
139
|
-
})).isOk()) return;
|
|
140
|
-
process$1.exit(1);
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
//#endregion
|
|
145
|
-
//#region src/commands/fix.ts
|
|
146
|
-
var fix_default = defineCommand({
|
|
147
|
-
command: "fix [files..]",
|
|
148
|
-
describe: "Run Biome linter and fix issues in files",
|
|
149
|
-
builder: (yargs$1) => yargs$1.positional("files", {
|
|
150
|
-
describe: "Specific files to fix (optional)",
|
|
151
|
-
type: "string",
|
|
152
|
-
array: true
|
|
153
|
-
}).option("unsafe", {
|
|
154
|
-
type: "boolean",
|
|
155
|
-
description: "Apply unsafe fixes"
|
|
156
|
-
}),
|
|
157
|
-
handler: async (argv) => {
|
|
158
|
-
if ((await safeTry(async function* () {
|
|
159
|
-
const packageManager = yield* getPackageManagerName();
|
|
160
|
-
const args = ["check", "--write"];
|
|
161
|
-
if (argv.unsafe) args.push("--unsafe");
|
|
162
|
-
if (argv.files && argv.files.length > 0) args.push(...argv.files);
|
|
163
|
-
yield* runCommand(dlxCommand(packageManager, biome.name, { args }), { stdio: "inherit" });
|
|
164
|
-
return ok(void 0);
|
|
165
|
-
})).isOk()) return;
|
|
166
|
-
process$1.exit(1);
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
//#endregion
|
|
171
|
-
//#region src/helpers/editors/vscode.ts
|
|
172
|
-
const vscode = {
|
|
173
|
-
config: {
|
|
174
|
-
"typescript.tsdk": "node_modules/typescript/lib",
|
|
175
|
-
"editor.formatOnSave": true,
|
|
176
|
-
"editor.formatOnPaste": true,
|
|
177
|
-
"editor.codeActionsOnSave": {
|
|
178
|
-
"source.organizeImports.biome": "explicit",
|
|
179
|
-
"source.fixAll.biome": "explicit"
|
|
180
|
-
},
|
|
181
|
-
"[javascript][typescript][javascriptreact][typescriptreact][json][jsonc][css][graphql]": { "editor.defaultFormatter": "biomejs.biome" }
|
|
182
|
-
},
|
|
183
|
-
exists: () => checkIfExists(join(process.cwd(), ".vscode", "settings.json")),
|
|
184
|
-
create: () => safeTry(async function* () {
|
|
185
|
-
const vscodePath = join(process.cwd(), ".vscode");
|
|
186
|
-
yield* fromPromise(mkdir(vscodePath, { recursive: true }), (error) => Fault.wrap(error).withTag("FAILED_TO_CREATE_DIRECTORY").withDescription("Failed to create .vscode directory", "We're unable to create the .vscode directory in the current directory.").withContext({ path: vscodePath }));
|
|
187
|
-
yield* fromPromise(writeFile(join(vscodePath, "settings.json"), JSON.stringify(vscode.config, null, 2)), (error) => Fault.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write .vscode/settings.json", "We're unable to write the .vscode/settings.json file in the current directory."));
|
|
188
|
-
return ok();
|
|
189
|
-
}),
|
|
190
|
-
update: () => safeTry(async function* () {
|
|
191
|
-
const vscodePath = join(process.cwd(), ".vscode", "settings.json");
|
|
192
|
-
const existingConfig = yield* parseJson(yield* fromPromise(readFile(vscodePath, "utf-8"), (error) => Fault.wrap(error).withTag("FAILED_TO_READ_FILE").withDescription("Failed to read .vscode/settings.json", "We're unable to read the .vscode/settings.json file in the current directory.").withContext({ path: vscodePath })));
|
|
193
|
-
const newConfig = yield* mergeConfig(vscode.config, existingConfig);
|
|
194
|
-
yield* fromPromise(writeFile(join(process.cwd(), ".vscode", "settings.json"), JSON.stringify(newConfig, null, 2)), (error) => Fault.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write .vscode/settings.json", "We're unable to write the .vscode/settings.json file in the current directory.").withContext({ path: vscodePath }));
|
|
195
|
-
return ok();
|
|
196
|
-
})
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
//#endregion
|
|
200
|
-
//#region src/helpers/tsconfig.ts
|
|
201
|
-
const tsconfig = {
|
|
202
|
-
config: { extends: "adamantite/tsconfig" },
|
|
203
|
-
exists: () => checkIfExists(join(process.cwd(), "tsconfig.json")),
|
|
204
|
-
create: () => fromPromise(writeFile(join(process.cwd(), "tsconfig.json"), JSON.stringify(tsconfig.config, null, 2)), (error) => Fault.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write tsconfig.json", "We're unable to write the tsconfig.json file in the current directory.")),
|
|
205
|
-
update: () => safeTry(async function* () {
|
|
206
|
-
const existingConfig = yield* parseJson(yield* fromPromise(readFile(join(process.cwd(), "tsconfig.json"), "utf-8"), (error) => Fault.wrap(error).withTag("FAILED_TO_READ_FILE").withDescription("Failed to read tsconfig.json", "We're unable to read the tsconfig.json file in the current directory.")));
|
|
207
|
-
const newConfig = yield* mergeConfig(tsconfig.config, existingConfig);
|
|
208
|
-
yield* fromPromise(writeFile(join(process.cwd(), "tsconfig.json"), JSON.stringify(newConfig, null, 2)), (error) => Fault.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write tsconfig.json", "We're unable to write the tsconfig.json file in the current directory."));
|
|
209
|
-
return ok();
|
|
210
|
-
})
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
//#endregion
|
|
214
|
-
//#region src/commands/init.ts
|
|
215
|
-
var init_default = defineCommand({
|
|
216
|
-
command: "init",
|
|
217
|
-
describe: "Initialize Adamantite in the current directory",
|
|
218
|
-
builder: (yargs$1) => yargs$1,
|
|
219
|
-
handler: async () => {
|
|
220
|
-
intro(getTitle());
|
|
221
|
-
const cwd = process$1.cwd();
|
|
222
|
-
const result = await safeTry(async function* () {
|
|
223
|
-
let packageJson = yield* readPackageJson();
|
|
224
|
-
const hasPnpmWorkspace = await checkIfExists(join(process$1.cwd(), "pnpm-workspace.yaml"));
|
|
225
|
-
const isMonorepo = packageJson.workspaces !== void 0 || hasPnpmWorkspace;
|
|
226
|
-
const shouldInstallScripts = yield* fromSafePromise(confirm({ message: "Do you want to add the `check` and `fix` scripts to your `package.json`?" })).andThen((r) => isCancel(r) ? err(Fault.create("OPERATION_CANCELLED")) : ok(r));
|
|
227
|
-
const shouldInstallMonorepoScripts = isMonorepo ? yield* fromSafePromise(confirm({ message: "We've detected a monorepo setup in your project. Would you like to install monorepo linting scripts?" })).andThen((r) => isCancel(r) ? err(Fault.create("OPERATION_CANCELLED")) : ok(r)) : false;
|
|
228
|
-
const shouldInstallTypeScriptPreset = yield* fromSafePromise(confirm({ message: "Adamantite provides a TypeScript preset to enforce strict type-safety. Would you like to install it?" })).andThen((r) => isCancel(r) ? err(Fault.create("OPERATION_CANCELLED")) : ok(r));
|
|
229
|
-
const selectedEditors = yield* fromSafePromise(multiselect({
|
|
230
|
-
message: "Which editors do you want to configure (recommended)?",
|
|
231
|
-
options: [{
|
|
232
|
-
label: "VSCode / Cursor / Windsurf",
|
|
233
|
-
value: "vscode"
|
|
234
|
-
}, {
|
|
235
|
-
label: "Zed (coming soon)",
|
|
236
|
-
value: "zed"
|
|
237
|
-
}],
|
|
238
|
-
required: false
|
|
239
|
-
})).andThen((r) => isCancel(r) ? err(Fault.create("OPERATION_CANCELLED")) : ok(r));
|
|
240
|
-
const installingDependencies = spinner();
|
|
241
|
-
installingDependencies.start("Installing dependencies...");
|
|
242
|
-
yield* fromPromise(addDevDependency("adamantite"), (error) => Fault.wrap(error).withTag("FAILED_TO_INSTALL_DEPENDENCY").withMessage("Failed to install Adamantite"));
|
|
243
|
-
yield* fromPromise(addDevDependency(`${biome.name}@${biome.version}`), (error) => Fault.wrap(error).withTag("FAILED_TO_INSTALL_DEPENDENCY").withMessage("Failed to install Biome"));
|
|
244
|
-
if (shouldInstallMonorepoScripts) yield* fromPromise(addDevDependency(`${sherif.name}@${sherif.version}`), (error) => Fault.wrap(error).withTag("FAILED_TO_INSTALL_DEPENDENCY").withMessage("Failed to install Sherif"));
|
|
245
|
-
installingDependencies.stop("Dependencies installed successfully");
|
|
246
|
-
const settingUpBiomeConfig = spinner();
|
|
247
|
-
settingUpBiomeConfig.start("Setting up Biome config...");
|
|
248
|
-
if ((await biome.exists()).path) {
|
|
249
|
-
settingUpBiomeConfig.message("Biome config found, updating...");
|
|
250
|
-
yield* biome.update();
|
|
251
|
-
settingUpBiomeConfig.stop("Biome config updated successfully");
|
|
252
|
-
} else {
|
|
253
|
-
settingUpBiomeConfig.message("Biome config not found, creating...");
|
|
254
|
-
yield* biome.create();
|
|
255
|
-
settingUpBiomeConfig.stop("Biome config created successfully");
|
|
256
|
-
}
|
|
257
|
-
if (shouldInstallScripts) {
|
|
258
|
-
const addingScripts = spinner();
|
|
259
|
-
packageJson = yield* readPackageJson();
|
|
260
|
-
addingScripts.start("Adding scripts to your `package.json`...");
|
|
261
|
-
if (!packageJson.scripts) packageJson.scripts = {};
|
|
262
|
-
packageJson.scripts.check = "adamantite check";
|
|
263
|
-
packageJson.scripts.fix = "adamantite fix";
|
|
264
|
-
if (shouldInstallMonorepoScripts) packageJson.scripts["lint:monorepo"] = "adamantite monorepo";
|
|
265
|
-
yield* fromPromise(writeFile(join(cwd, "package.json"), JSON.stringify(packageJson, null, 2)), (error) => Fault.wrap(error).withTag("FAILED_TO_WRITE_FILE").withDescription("Failed to write package.json", "We're unable to update the package.json file.").withContext({ path: join(cwd, "package.json") }));
|
|
266
|
-
addingScripts.stop("Scripts added to your `package.json`");
|
|
267
|
-
}
|
|
268
|
-
if (shouldInstallTypeScriptPreset) {
|
|
269
|
-
const settingUpTypeScriptConfig = spinner();
|
|
270
|
-
settingUpTypeScriptConfig.start("Setting up TypeScript config...");
|
|
271
|
-
if (await tsconfig.exists()) {
|
|
272
|
-
settingUpTypeScriptConfig.message("`tsconfig.json` found, updating...");
|
|
273
|
-
yield* tsconfig.update();
|
|
274
|
-
settingUpTypeScriptConfig.stop("`tsconfig.json` updated successfully");
|
|
275
|
-
} else {
|
|
276
|
-
settingUpTypeScriptConfig.message("`tsconfig.json` not found, creating...");
|
|
277
|
-
yield* tsconfig.create();
|
|
278
|
-
settingUpTypeScriptConfig.stop("`tsconfig.json` created successfully");
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
if (selectedEditors.length > 0) {
|
|
282
|
-
const settingUpEditorConfig = spinner();
|
|
283
|
-
settingUpEditorConfig.start("Setting up editor config...");
|
|
284
|
-
if (selectedEditors.includes("vscode")) {
|
|
285
|
-
const settingUpVSCodeConfig = spinner();
|
|
286
|
-
settingUpVSCodeConfig.start("Setting up VSCode config...");
|
|
287
|
-
if (await vscode.exists()) {
|
|
288
|
-
settingUpVSCodeConfig.message("VSCode settings found, updating...");
|
|
289
|
-
yield* vscode.update();
|
|
290
|
-
settingUpVSCodeConfig.stop("VSCode settings updated with Adamantite preset");
|
|
291
|
-
} else {
|
|
292
|
-
settingUpVSCodeConfig.message("VSCode settings not found, creating...");
|
|
293
|
-
yield* vscode.create();
|
|
294
|
-
settingUpVSCodeConfig.stop("VSCode settings created with Adamantite preset");
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
if (selectedEditors.includes("zed")) log.warning("Zed configuration coming soon...");
|
|
298
|
-
settingUpEditorConfig.stop("Editor config set up successfully");
|
|
299
|
-
}
|
|
300
|
-
return ok();
|
|
301
|
-
});
|
|
302
|
-
if (result.isOk()) {
|
|
303
|
-
outro("💠 Adamantite initialized successfully!");
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
306
|
-
if (result.error.tag === "OPERATION_CANCELLED") {
|
|
307
|
-
cancel("You've cancelled the initialization process.");
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
log.error(result.error.message);
|
|
311
|
-
cancel("Failed to initialize Adamantite");
|
|
312
|
-
process$1.exit(1);
|
|
313
|
-
}
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
//#endregion
|
|
317
|
-
//#region src/commands/monorepo.ts
|
|
318
|
-
var monorepo_default = defineCommand({
|
|
319
|
-
command: "monorepo",
|
|
320
|
-
describe: "Lint and automatically fix monorepo-specific issues using Sherif",
|
|
321
|
-
builder: (yargs$1) => yargs$1,
|
|
322
|
-
handler: async () => {
|
|
323
|
-
if ((await safeTry(async function* () {
|
|
324
|
-
yield* runCommand(dlxCommand(yield* getPackageManagerName(), sherif.name, { args: ["--fix"] }), { stdio: "inherit" });
|
|
325
|
-
return ok(void 0);
|
|
326
|
-
})).isOk()) return;
|
|
327
|
-
process$1.exit(1);
|
|
328
|
-
}
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
//#endregion
|
|
332
|
-
//#region src/commands/update.ts
|
|
333
|
-
var update_default = defineCommand({
|
|
334
|
-
command: "update",
|
|
335
|
-
describe: "Update adamantite dependencies to latest compatible versions",
|
|
336
|
-
builder: (yargs$1) => yargs$1,
|
|
337
|
-
handler: async () => {
|
|
338
|
-
intro(getTitle());
|
|
339
|
-
const result = await safeTry(async function* () {
|
|
340
|
-
const packageJson = yield* readPackageJson();
|
|
341
|
-
const updates = [];
|
|
342
|
-
for (const pkg of [biome, sherif]) {
|
|
343
|
-
const dependency = packageJson.devDependencies?.[pkg.name];
|
|
344
|
-
if (dependency && dependency !== pkg.version) updates.push({
|
|
345
|
-
name: pkg.name,
|
|
346
|
-
currentVersion: dependency,
|
|
347
|
-
targetVersion: pkg.version,
|
|
348
|
-
isDevDependency: true
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
if (updates.length === 0) {
|
|
352
|
-
log.success("All adamantite dependencies are already up to date!");
|
|
353
|
-
return ok("no-updates");
|
|
354
|
-
}
|
|
355
|
-
log.message("The following dependencies will be updated:");
|
|
356
|
-
log.message("");
|
|
357
|
-
for (const dep of updates) log.message(` ${dep.name}: ${dep.currentVersion} → ${dep.targetVersion}`);
|
|
358
|
-
log.message("");
|
|
359
|
-
if (!(yield* fromSafePromise(confirm({ message: "Do you want to proceed with these updates?" })).andThen((r) => isCancel(r) ? err(Fault.create("OPERATION_CANCELLED")) : ok(r)))) return ok("cancelled");
|
|
360
|
-
const s = spinner();
|
|
361
|
-
s.start("Updating dependencies...");
|
|
362
|
-
for (const dep of updates) yield* fromPromise(addDevDependency(`${dep.name}@${dep.targetVersion}`), (error) => Fault.wrap(error).withTag("FAILED_TO_INSTALL_DEPENDENCY").withMessage(`Failed to update ${dep.name}`));
|
|
363
|
-
s.stop("Dependencies updated successfully");
|
|
364
|
-
return ok("updated");
|
|
365
|
-
});
|
|
366
|
-
if (result.isOk()) {
|
|
367
|
-
if (result.value === "no-updates") outro("💠 No updates needed");
|
|
368
|
-
else if (result.value === "cancelled") outro("💠 Update cancelled");
|
|
369
|
-
else if (result.value === "updated") outro("💠 Dependencies updated successfully!");
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
if (result.error.tag === "OPERATION_CANCELLED") {
|
|
373
|
-
cancel("You've cancelled the update process.");
|
|
374
|
-
return;
|
|
375
|
-
}
|
|
376
|
-
log.error(result.error.message);
|
|
377
|
-
cancel("Failed to update dependencies");
|
|
378
|
-
process$1.exit(1);
|
|
379
|
-
}
|
|
380
|
-
});
|
|
381
|
-
|
|
382
|
-
//#endregion
|
|
383
|
-
//#region src/version.ts
|
|
384
|
-
function getPackageVersion() {
|
|
385
|
-
return JSON.parse(readFileSync(join(process.cwd(), "package.json"), "utf-8")).version;
|
|
386
|
-
}
|
|
387
|
-
const version = getPackageVersion();
|
|
388
|
-
var version_default = version;
|
|
389
|
-
|
|
390
|
-
//#endregion
|
|
391
|
-
//#region src/index.ts
|
|
392
|
-
yargs(hideBin(process.argv)).scriptName("adamantite").version(version_default).command(check_default).command(ci_default).command(fix_default).command(init_default).command(monorepo_default).command(update_default).demandCommand(1).strict().help().parse();
|
|
393
|
-
|
|
394
|
-
//#endregion
|
|
395
|
-
export { };
|