@mayrlabs/setup-project 0.1.4 → 0.1.6
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/CHANGELOG.md +12 -0
- package/dist/index.js +681 -405
- package/dist/index.mjs +749 -418
- package/package.json +4 -1
package/dist/index.mjs
CHANGED
|
@@ -65,34 +65,152 @@ var init_pm = __esm({
|
|
|
65
65
|
}
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
-
// src/
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
68
|
+
// src/constants/options.ts
|
|
69
|
+
var TOOL_OPTIONS, HUSKY_HOOK_OPTIONS, FORMATTER_OPTIONS, LINTER_OPTIONS, LINT_STAGED_EXTENSIONS, ENV_VARIANT_OPTIONS, ENV_VALIDATOR_OPTIONS, ENV_PRESET_OPTIONS, ENV_SPLIT_OPTIONS, TEST_RUNNER_OPTIONS, EDITOR_CONFIG_OPTIONS, LICENSE_TYPE_OPTIONS;
|
|
70
|
+
var init_options = __esm({
|
|
71
|
+
"src/constants/options.ts"() {
|
|
72
|
+
"use strict";
|
|
73
|
+
init_esm_shims();
|
|
74
|
+
TOOL_OPTIONS = [
|
|
75
|
+
{ value: "husky", label: "Husky" },
|
|
76
|
+
{ value: "formatter", label: "Formatter (Prettier/Oxfmt)" },
|
|
77
|
+
{ value: "linter", label: "Linter (Eslint/Oxlint)" },
|
|
78
|
+
{ value: "lint-staged", label: "Lint-staged" },
|
|
79
|
+
{ value: "env", label: "Env Validation (@t3-oss/env)" },
|
|
80
|
+
{ value: "test", label: "Test Runner (Vitest/Jest)" },
|
|
81
|
+
{ value: "editorConfig", label: "EditorConfig" },
|
|
82
|
+
{ value: "license", label: "License" }
|
|
83
|
+
];
|
|
84
|
+
HUSKY_HOOK_OPTIONS = [
|
|
76
85
|
{ value: "lint-staged", label: "lint-staged" },
|
|
77
86
|
{ value: "custom", label: "Custom script" },
|
|
78
87
|
{ value: "none", label: "None" }
|
|
79
|
-
]
|
|
80
|
-
|
|
81
|
-
|
|
88
|
+
];
|
|
89
|
+
FORMATTER_OPTIONS = [
|
|
90
|
+
{ value: "prettier", label: "Prettier" },
|
|
91
|
+
{ value: "oxfmt", label: "Oxfmt" }
|
|
92
|
+
];
|
|
93
|
+
LINTER_OPTIONS = [
|
|
94
|
+
{ value: "eslint", label: "ESLint" },
|
|
95
|
+
{ value: "oxlint", label: "Oxlint" }
|
|
96
|
+
];
|
|
97
|
+
LINT_STAGED_EXTENSIONS = [
|
|
98
|
+
{ value: "js", label: "js" },
|
|
99
|
+
{ value: "ts", label: "ts" },
|
|
100
|
+
{ value: "jsx", label: "jsx" },
|
|
101
|
+
{ value: "tsx", label: "tsx" },
|
|
102
|
+
{ value: "html", label: "html" },
|
|
103
|
+
{ value: "vue", label: "vue" },
|
|
104
|
+
{ value: "svelte", label: "svelte" },
|
|
105
|
+
{ value: "css", label: "css" },
|
|
106
|
+
{ value: "scss", label: "scss" },
|
|
107
|
+
{ value: "json", label: "json" },
|
|
108
|
+
{ value: "yaml", label: "yaml" },
|
|
109
|
+
{ value: "md", label: "md" }
|
|
110
|
+
];
|
|
111
|
+
ENV_VARIANT_OPTIONS = [
|
|
112
|
+
{ value: "@t3-oss/env-nextjs", label: "Next.js" },
|
|
113
|
+
{ value: "@t3-oss/env-nuxt", label: "Nuxt" },
|
|
114
|
+
{ value: "@t3-oss/env-core", label: "Core" }
|
|
115
|
+
];
|
|
116
|
+
ENV_VALIDATOR_OPTIONS = [
|
|
117
|
+
{ value: "zod", label: "Zod" },
|
|
118
|
+
{ value: "valibot", label: "Valibot" },
|
|
119
|
+
{ value: "arktype", label: "Arktype" }
|
|
120
|
+
];
|
|
121
|
+
ENV_PRESET_OPTIONS = [
|
|
122
|
+
{ value: "netlify", label: "Netlify" },
|
|
123
|
+
{ value: "vercel", label: "Vercel" },
|
|
124
|
+
{ value: "neonVercel", label: "Neon (Vercel)" },
|
|
125
|
+
{ value: "supabaseVercel", label: "Supabase (Vercel)" },
|
|
126
|
+
{ value: "uploadThing", label: "UploadThing" },
|
|
127
|
+
{ value: "render", label: "Render" },
|
|
128
|
+
{ value: "railway", label: "Railway" },
|
|
129
|
+
{ value: "fly.io", label: "Fly.io" },
|
|
130
|
+
{ value: "upstashRedis", label: "Upstash Redis" },
|
|
131
|
+
{ value: "coolify", label: "Coolify" },
|
|
132
|
+
{ value: "vite", label: "Vite" },
|
|
133
|
+
{ value: "wxt", label: "WXT" }
|
|
134
|
+
];
|
|
135
|
+
ENV_SPLIT_OPTIONS = [
|
|
136
|
+
{ value: "split", label: "Split (env/server.ts, env/client.ts)" },
|
|
137
|
+
{ value: "joined", label: "Joined (env.ts)" }
|
|
138
|
+
];
|
|
139
|
+
TEST_RUNNER_OPTIONS = [
|
|
140
|
+
{ value: "vitest", label: "Vitest" },
|
|
141
|
+
{ value: "jest", label: "Jest" }
|
|
142
|
+
];
|
|
143
|
+
EDITOR_CONFIG_OPTIONS = [
|
|
144
|
+
{ value: "default", label: "Default (Spaces 2)" },
|
|
145
|
+
{ value: "spaces4", label: "Spaces 4" },
|
|
146
|
+
{ value: "tabs", label: "Tabs" }
|
|
147
|
+
];
|
|
148
|
+
LICENSE_TYPE_OPTIONS = [
|
|
149
|
+
{ value: "MIT", label: "MIT" },
|
|
150
|
+
{ value: "ISC", label: "ISC" },
|
|
151
|
+
{ value: "Apache-2.0", label: "Apache 2.0" },
|
|
152
|
+
{ value: "UNLICENSED", label: "UNLICENSED" }
|
|
153
|
+
];
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// src/utils/handle-cancel.ts
|
|
158
|
+
import { cancel, isCancel, confirm } from "@clack/prompts";
|
|
159
|
+
async function withCancelHandling(promptFn, cancelMessage = "Operation cancelled.") {
|
|
160
|
+
while (true) {
|
|
161
|
+
const response = await promptFn();
|
|
162
|
+
if (isCancel(response)) {
|
|
163
|
+
const shouldCancel = await confirm({
|
|
164
|
+
message: "Do you really want to cancel options selection?"
|
|
165
|
+
});
|
|
166
|
+
if (isCancel(shouldCancel) || shouldCancel) {
|
|
167
|
+
cancel(cancelMessage);
|
|
168
|
+
process.exit(0);
|
|
169
|
+
}
|
|
170
|
+
continue;
|
|
171
|
+
} else {
|
|
172
|
+
return response;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
var init_handle_cancel = __esm({
|
|
177
|
+
"src/utils/handle-cancel.ts"() {
|
|
178
|
+
"use strict";
|
|
179
|
+
init_esm_shims();
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// src/services/husky.ts
|
|
184
|
+
import { select, log, text } from "@clack/prompts";
|
|
185
|
+
import { execa as execa2 } from "execa";
|
|
186
|
+
import fs from "fs-extra";
|
|
187
|
+
import pc from "picocolors";
|
|
188
|
+
async function promptHusky(config2) {
|
|
189
|
+
log.message(pc.bgMagenta(pc.black(" Husky Configuration ")));
|
|
190
|
+
const hookType = await withCancelHandling(
|
|
191
|
+
async () => select({
|
|
192
|
+
message: "What pre-commit hook would you like to use?",
|
|
193
|
+
options: HUSKY_HOOK_OPTIONS
|
|
194
|
+
})
|
|
195
|
+
);
|
|
196
|
+
const huskyConfig = config2.get("husky");
|
|
197
|
+
huskyConfig.options = { hookType };
|
|
82
198
|
if (hookType === "lint-staged") {
|
|
83
|
-
|
|
199
|
+
config2.enableTool("lintStaged");
|
|
84
200
|
} else if (hookType === "custom") {
|
|
85
|
-
const script = await
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
201
|
+
const script = await withCancelHandling(
|
|
202
|
+
async () => text({
|
|
203
|
+
message: "Enter your custom pre-commit script:",
|
|
204
|
+
placeholder: huskyConfig.options.customScript,
|
|
205
|
+
validate(value) {
|
|
206
|
+
if (value.length === 0) return "Value is required!";
|
|
207
|
+
}
|
|
208
|
+
})
|
|
209
|
+
);
|
|
210
|
+
huskyConfig.options.customScript = script;
|
|
93
211
|
}
|
|
94
212
|
}
|
|
95
|
-
async function installHusky(
|
|
213
|
+
async function installHusky(config2) {
|
|
96
214
|
await installPackages(["husky"], true);
|
|
97
215
|
try {
|
|
98
216
|
await execa2("npx", ["husky", "init"]);
|
|
@@ -100,12 +218,15 @@ async function installHusky(config) {
|
|
|
100
218
|
await execa2("npm", ["pkg", "set", "scripts.prepare=husky"]);
|
|
101
219
|
await execa2("npm", ["run", "prepare"]);
|
|
102
220
|
}
|
|
103
|
-
|
|
221
|
+
const husky = config2.get("husky");
|
|
222
|
+
const hookType = husky.options.hookType;
|
|
223
|
+
const customScript = husky.options.customScript;
|
|
224
|
+
if (hookType === "lint-staged") {
|
|
104
225
|
await fs.outputFile(".husky/pre-commit", "npx lint-staged\n", {
|
|
105
226
|
mode: 493
|
|
106
227
|
});
|
|
107
|
-
} else if (
|
|
108
|
-
await fs.outputFile(".husky/pre-commit", `${
|
|
228
|
+
} else if (hookType === "custom" && customScript) {
|
|
229
|
+
await fs.outputFile(".husky/pre-commit", `${customScript}
|
|
109
230
|
`, {
|
|
110
231
|
mode: 493
|
|
111
232
|
});
|
|
@@ -116,26 +237,30 @@ var init_husky = __esm({
|
|
|
116
237
|
"use strict";
|
|
117
238
|
init_esm_shims();
|
|
118
239
|
init_pm();
|
|
240
|
+
init_options();
|
|
241
|
+
init_handle_cancel();
|
|
119
242
|
}
|
|
120
243
|
});
|
|
121
244
|
|
|
122
245
|
// src/services/formatter.ts
|
|
123
|
-
import { select as select2 } from "@clack/prompts";
|
|
246
|
+
import { select as select2, log as log2 } from "@clack/prompts";
|
|
124
247
|
import fs2 from "fs-extra";
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
248
|
+
import pc2 from "picocolors";
|
|
249
|
+
async function promptFormatter(config2) {
|
|
250
|
+
const formatterConfig = config2.get("formatter");
|
|
251
|
+
log2.message(pc2.bgBlue(pc2.black(" Formatter Configuration ")));
|
|
252
|
+
const formatter = await withCancelHandling(
|
|
253
|
+
async () => select2({
|
|
128
254
|
message: "Select a formatter:",
|
|
129
|
-
options:
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
config.formatterChoice = formatter;
|
|
135
|
-
}
|
|
255
|
+
options: FORMATTER_OPTIONS,
|
|
256
|
+
initialValue: formatterConfig.options.choice
|
|
257
|
+
})
|
|
258
|
+
);
|
|
259
|
+
formatterConfig.options = { choice: formatter };
|
|
136
260
|
}
|
|
137
|
-
async function installFormatter(
|
|
138
|
-
|
|
261
|
+
async function installFormatter(config2) {
|
|
262
|
+
const choice = config2.get("formatter").options.choice;
|
|
263
|
+
if (choice === "prettier") {
|
|
139
264
|
await installPackages(["prettier"], true);
|
|
140
265
|
const configContent = {
|
|
141
266
|
semi: true,
|
|
@@ -145,7 +270,7 @@ async function installFormatter(config) {
|
|
|
145
270
|
tabWidth: 2
|
|
146
271
|
};
|
|
147
272
|
await fs2.writeJson(".prettierrc", configContent, { spaces: 2 });
|
|
148
|
-
} else if (
|
|
273
|
+
} else if (choice === "oxfmt") {
|
|
149
274
|
await installPackages(["oxfmt"], true);
|
|
150
275
|
}
|
|
151
276
|
}
|
|
@@ -154,26 +279,30 @@ var init_formatter = __esm({
|
|
|
154
279
|
"use strict";
|
|
155
280
|
init_esm_shims();
|
|
156
281
|
init_pm();
|
|
282
|
+
init_options();
|
|
283
|
+
init_handle_cancel();
|
|
157
284
|
}
|
|
158
285
|
});
|
|
159
286
|
|
|
160
287
|
// src/services/linter.ts
|
|
161
|
-
import { select as select3 } from "@clack/prompts";
|
|
288
|
+
import { select as select3, log as log3 } from "@clack/prompts";
|
|
162
289
|
import fs3 from "fs-extra";
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
290
|
+
import pc3 from "picocolors";
|
|
291
|
+
async function promptLinter(config2) {
|
|
292
|
+
const linterConfig = config2.get("linter");
|
|
293
|
+
log3.message(pc3.bgYellow(pc3.black(" Linter Configuration ")));
|
|
294
|
+
const linter = await withCancelHandling(
|
|
295
|
+
async () => select3({
|
|
166
296
|
message: "Select a linter:",
|
|
167
|
-
options:
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
config.linterChoice = linter;
|
|
173
|
-
}
|
|
297
|
+
options: LINTER_OPTIONS,
|
|
298
|
+
initialValue: linterConfig.options.choice
|
|
299
|
+
})
|
|
300
|
+
);
|
|
301
|
+
linterConfig.options = { choice: linter };
|
|
174
302
|
}
|
|
175
|
-
async function installLinter(
|
|
176
|
-
|
|
303
|
+
async function installLinter(config2) {
|
|
304
|
+
const choice = config2.get("linter").options.choice;
|
|
305
|
+
if (choice === "eslint") {
|
|
177
306
|
await installPackages(["eslint"], true);
|
|
178
307
|
const configContent = {
|
|
179
308
|
extends: ["eslint:recommended"],
|
|
@@ -187,7 +316,7 @@ async function installLinter(config) {
|
|
|
187
316
|
}
|
|
188
317
|
};
|
|
189
318
|
await fs3.writeJson(".eslintrc.json", configContent, { spaces: 2 });
|
|
190
|
-
} else if (
|
|
319
|
+
} else if (choice === "oxlint") {
|
|
191
320
|
await installPackages(["oxlint"], true);
|
|
192
321
|
}
|
|
193
322
|
}
|
|
@@ -196,73 +325,63 @@ var init_linter = __esm({
|
|
|
196
325
|
"use strict";
|
|
197
326
|
init_esm_shims();
|
|
198
327
|
init_pm();
|
|
328
|
+
init_options();
|
|
329
|
+
init_handle_cancel();
|
|
199
330
|
}
|
|
200
331
|
});
|
|
201
332
|
|
|
202
333
|
// src/services/lint-staged.ts
|
|
203
|
-
import { multiselect } from "@clack/prompts";
|
|
334
|
+
import { multiselect, log as log4 } from "@clack/prompts";
|
|
204
335
|
import fs4 from "fs-extra";
|
|
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
|
-
{ value: "svelte", label: "svelte" }
|
|
234
|
-
],
|
|
235
|
-
required: false
|
|
236
|
-
});
|
|
237
|
-
config.lintStagedLintExtensions = lintExtensions;
|
|
238
|
-
config.lintStagedFormatExtensions = formatExtensions;
|
|
239
|
-
if (lintExtensions.length > 0 && !config.linterChoice) {
|
|
240
|
-
await promptLinter(config);
|
|
241
|
-
config.linter = true;
|
|
242
|
-
}
|
|
243
|
-
if (formatExtensions.length > 0 && !config.formatterChoice) {
|
|
244
|
-
await promptFormatter(config);
|
|
245
|
-
config.formatter = true;
|
|
336
|
+
import pc4 from "picocolors";
|
|
337
|
+
async function promptLintStaged(config2) {
|
|
338
|
+
log4.message(pc4.bgGreen(pc4.black(" Lint-staged Configuration ")));
|
|
339
|
+
const lintExtensions = await withCancelHandling(
|
|
340
|
+
async () => multiselect({
|
|
341
|
+
message: "Select extensions to lint:",
|
|
342
|
+
options: LINT_STAGED_EXTENSIONS,
|
|
343
|
+
required: false
|
|
344
|
+
})
|
|
345
|
+
);
|
|
346
|
+
const formatExtensions = await withCancelHandling(
|
|
347
|
+
async () => multiselect({
|
|
348
|
+
message: "Select extensions to format:",
|
|
349
|
+
options: LINT_STAGED_EXTENSIONS,
|
|
350
|
+
required: false
|
|
351
|
+
})
|
|
352
|
+
);
|
|
353
|
+
config2.get("lintStaged").options = {
|
|
354
|
+
lintExtensions,
|
|
355
|
+
formatExtensions
|
|
356
|
+
};
|
|
357
|
+
if (lintExtensions.length > 0 && !config2.get("linter").selected) {
|
|
358
|
+
await promptLinter(config2);
|
|
359
|
+
config2.enableTool("linter");
|
|
360
|
+
}
|
|
361
|
+
if (formatExtensions.length > 0 && !config2.get("formatter").selected) {
|
|
362
|
+
await promptFormatter(config2);
|
|
363
|
+
config2.enableTool("formatter");
|
|
246
364
|
}
|
|
247
365
|
}
|
|
248
|
-
async function installLintStaged(
|
|
366
|
+
async function installLintStaged(config2) {
|
|
249
367
|
await installPackages(["lint-staged"], true);
|
|
250
368
|
const lintStagedConfig = {};
|
|
251
|
-
const
|
|
252
|
-
const
|
|
369
|
+
const lintStagedOptions = config2.get("lintStaged").options;
|
|
370
|
+
const lintExts = lintStagedOptions?.lintExtensions || [];
|
|
371
|
+
const formatExts = lintStagedOptions?.formatExtensions || [];
|
|
253
372
|
if (lintExts.length > 0) {
|
|
254
|
-
await installLinter(
|
|
373
|
+
await installLinter(config2);
|
|
255
374
|
const glob = `*.{${lintExts.join(",")}}`;
|
|
256
|
-
if (
|
|
375
|
+
if (config2.get("linter").options.choice === "oxlint") {
|
|
257
376
|
lintStagedConfig[glob] = ["npx oxlint --fix"];
|
|
258
377
|
} else {
|
|
259
378
|
lintStagedConfig[glob] = ["eslint --fix"];
|
|
260
379
|
}
|
|
261
380
|
}
|
|
262
381
|
if (formatExts.length > 0) {
|
|
263
|
-
await installFormatter(
|
|
382
|
+
await installFormatter(config2);
|
|
264
383
|
const glob = `*.{${formatExts.join(",")}}`;
|
|
265
|
-
if (
|
|
384
|
+
if (config2.get("formatter").options.choice === "oxfmt") {
|
|
266
385
|
lintStagedConfig[glob] = ["npx oxfmt"];
|
|
267
386
|
} else {
|
|
268
387
|
lintStagedConfig[glob] = ["prettier --write"];
|
|
@@ -277,89 +396,81 @@ var init_lint_staged = __esm({
|
|
|
277
396
|
init_pm();
|
|
278
397
|
init_formatter();
|
|
279
398
|
init_linter();
|
|
399
|
+
init_options();
|
|
400
|
+
init_handle_cancel();
|
|
280
401
|
}
|
|
281
402
|
});
|
|
282
403
|
|
|
283
404
|
// src/services/env.ts
|
|
284
|
-
import { select as
|
|
405
|
+
import { select as select4, confirm as confirm2, text as text2, multiselect as multiselect2, log as log5 } from "@clack/prompts";
|
|
285
406
|
import fs5 from "fs-extra";
|
|
286
407
|
import path2 from "path";
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
});
|
|
309
|
-
config.envInstallPresets = installPresets;
|
|
408
|
+
import pc5 from "picocolors";
|
|
409
|
+
async function promptEnv(config2) {
|
|
410
|
+
log5.message(pc5.bgCyan(pc5.black(" Env Validation Configuration ")));
|
|
411
|
+
const variant = await withCancelHandling(
|
|
412
|
+
async () => select4({
|
|
413
|
+
message: "Which @t3-oss/env variant?",
|
|
414
|
+
options: ENV_VARIANT_OPTIONS
|
|
415
|
+
})
|
|
416
|
+
);
|
|
417
|
+
const validator = await withCancelHandling(
|
|
418
|
+
async () => select4({
|
|
419
|
+
message: "Which validator?",
|
|
420
|
+
options: ENV_VALIDATOR_OPTIONS
|
|
421
|
+
})
|
|
422
|
+
);
|
|
423
|
+
const installPresets = await withCancelHandling(
|
|
424
|
+
async () => confirm2({
|
|
425
|
+
message: "Install presets?"
|
|
426
|
+
})
|
|
427
|
+
);
|
|
428
|
+
let presets;
|
|
310
429
|
if (installPresets) {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
{ value: "uploadThing", label: "UploadThing" },
|
|
319
|
-
{ value: "render", label: "Render" },
|
|
320
|
-
{ value: "railway", label: "Railway" },
|
|
321
|
-
{ value: "fly.io", label: "Fly.io" },
|
|
322
|
-
{ value: "upstashRedis", label: "Upstash Redis" },
|
|
323
|
-
{ value: "coolify", label: "Coolify" },
|
|
324
|
-
{ value: "vite", label: "Vite" },
|
|
325
|
-
{ value: "wxt", label: "WXT" }
|
|
326
|
-
],
|
|
327
|
-
required: false
|
|
328
|
-
});
|
|
329
|
-
config.envPresets = presets;
|
|
430
|
+
presets = await withCancelHandling(
|
|
431
|
+
async () => multiselect2({
|
|
432
|
+
message: "Select preset to extend:",
|
|
433
|
+
options: ENV_PRESET_OPTIONS,
|
|
434
|
+
required: false
|
|
435
|
+
})
|
|
436
|
+
);
|
|
330
437
|
}
|
|
331
|
-
const split = await
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
438
|
+
const split = await withCancelHandling(
|
|
439
|
+
async () => select4({
|
|
440
|
+
message: "Split or Joined env files?",
|
|
441
|
+
options: ENV_SPLIT_OPTIONS
|
|
442
|
+
})
|
|
443
|
+
);
|
|
444
|
+
const location = await withCancelHandling(
|
|
445
|
+
async () => text2({
|
|
446
|
+
message: "Where should the environment files be created?",
|
|
447
|
+
initialValue: config2.get("env").options.location || "src/lib",
|
|
448
|
+
placeholder: "src/lib"
|
|
449
|
+
})
|
|
450
|
+
);
|
|
451
|
+
config2.get("env").options = {
|
|
452
|
+
variant,
|
|
453
|
+
validator,
|
|
454
|
+
installPresets,
|
|
455
|
+
presets: presets || [],
|
|
456
|
+
split,
|
|
457
|
+
location
|
|
458
|
+
};
|
|
345
459
|
}
|
|
346
|
-
async function installEnv(
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
}
|
|
352
|
-
const targetDir = config.envLocation;
|
|
353
|
-
await fs5.ensureDir(targetDir);
|
|
354
|
-
const presetImport = config.envPresets && config.envPresets.length > 0 ? `// Presets: ${config.envPresets.join(", ")}
|
|
460
|
+
async function installEnv(config2) {
|
|
461
|
+
const envOptions = config2.get("env").options;
|
|
462
|
+
const { variant, validator, location, presets, split } = envOptions;
|
|
463
|
+
await installPackages([variant, validator], true);
|
|
464
|
+
await fs5.ensureDir(location);
|
|
465
|
+
const presetImport = presets && presets.length > 0 ? `// Presets: ${presets.join(", ")}
|
|
355
466
|
` : "";
|
|
356
|
-
const content = `import { createEnv } from "${
|
|
357
|
-
import { ${
|
|
467
|
+
const content = `import { createEnv } from "${variant}";
|
|
468
|
+
import { ${validator} } from "${validator}";
|
|
358
469
|
|
|
359
470
|
${presetImport}`;
|
|
360
|
-
if (
|
|
471
|
+
if (split === "split") {
|
|
361
472
|
await fs5.outputFile(
|
|
362
|
-
path2.join(
|
|
473
|
+
path2.join(location, "env/server.ts"),
|
|
363
474
|
`${content}
|
|
364
475
|
// Server env definition
|
|
365
476
|
export const env = createEnv({
|
|
@@ -370,7 +481,7 @@ export const env = createEnv({
|
|
|
370
481
|
});`
|
|
371
482
|
);
|
|
372
483
|
await fs5.outputFile(
|
|
373
|
-
path2.join(
|
|
484
|
+
path2.join(location, "env/client.ts"),
|
|
374
485
|
`${content}
|
|
375
486
|
// Client env definition
|
|
376
487
|
export const env = createEnv({
|
|
@@ -384,7 +495,7 @@ export const env = createEnv({
|
|
|
384
495
|
);
|
|
385
496
|
} else {
|
|
386
497
|
await fs5.outputFile(
|
|
387
|
-
path2.join(
|
|
498
|
+
path2.join(location, "env.ts"),
|
|
388
499
|
`${content}
|
|
389
500
|
// Joined env definition
|
|
390
501
|
export const env = createEnv({
|
|
@@ -406,24 +517,28 @@ var init_env = __esm({
|
|
|
406
517
|
"use strict";
|
|
407
518
|
init_esm_shims();
|
|
408
519
|
init_pm();
|
|
520
|
+
init_options();
|
|
521
|
+
init_handle_cancel();
|
|
409
522
|
}
|
|
410
523
|
});
|
|
411
524
|
|
|
412
525
|
// src/services/test.ts
|
|
413
|
-
import { select as
|
|
526
|
+
import { select as select5, log as log6 } from "@clack/prompts";
|
|
414
527
|
import fs6 from "fs-extra";
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
528
|
+
import pc6 from "picocolors";
|
|
529
|
+
async function promptTest(config2) {
|
|
530
|
+
log6.message(pc6.bgRed(pc6.black(" Test Runner Configuration ")));
|
|
531
|
+
const runner = await withCancelHandling(
|
|
532
|
+
async () => select5({
|
|
533
|
+
message: "Select a test runner:",
|
|
534
|
+
options: TEST_RUNNER_OPTIONS
|
|
535
|
+
})
|
|
536
|
+
);
|
|
537
|
+
config2.get("test").options = { runner };
|
|
424
538
|
}
|
|
425
|
-
async function installTest(
|
|
426
|
-
|
|
539
|
+
async function installTest(config2) {
|
|
540
|
+
const runner = config2.get("test").options.runner;
|
|
541
|
+
if (runner === "vitest") {
|
|
427
542
|
await installPackages(["vitest"], true);
|
|
428
543
|
const configFile = "vitest.config.ts";
|
|
429
544
|
if (!await fs6.pathExists(configFile)) {
|
|
@@ -439,7 +554,7 @@ export default defineConfig({
|
|
|
439
554
|
`
|
|
440
555
|
);
|
|
441
556
|
}
|
|
442
|
-
} else if (
|
|
557
|
+
} else if (runner === "jest") {
|
|
443
558
|
await installPackages(["jest", "ts-jest", "@types/jest"], true);
|
|
444
559
|
const configFile = "jest.config.js";
|
|
445
560
|
if (!await fs6.pathExists(configFile)) {
|
|
@@ -460,30 +575,35 @@ var init_test = __esm({
|
|
|
460
575
|
"use strict";
|
|
461
576
|
init_esm_shims();
|
|
462
577
|
init_pm();
|
|
578
|
+
init_options();
|
|
579
|
+
init_handle_cancel();
|
|
463
580
|
}
|
|
464
581
|
});
|
|
465
582
|
|
|
466
583
|
// src/services/editor-config.ts
|
|
467
|
-
import { select as
|
|
584
|
+
import { select as select6, log as log7 } from "@clack/prompts";
|
|
468
585
|
import fs7 from "fs-extra";
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
586
|
+
import pc7 from "picocolors";
|
|
587
|
+
async function promptEditorConfig(config2) {
|
|
588
|
+
log7.message(pc7.bgWhite(pc7.black(" EditorConfig Configuration ")));
|
|
589
|
+
const currentPreset = config2.get("editorConfig").options.preset;
|
|
590
|
+
const preset = await withCancelHandling(
|
|
591
|
+
async () => select6({
|
|
592
|
+
message: "Select EditorConfig preset:",
|
|
593
|
+
options: EDITOR_CONFIG_OPTIONS,
|
|
594
|
+
initialValue: currentPreset
|
|
595
|
+
})
|
|
596
|
+
);
|
|
597
|
+
config2.get("editorConfig").options = { preset };
|
|
479
598
|
}
|
|
480
|
-
async function installEditorConfig(
|
|
599
|
+
async function installEditorConfig(config2) {
|
|
481
600
|
let content = "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n";
|
|
482
|
-
|
|
601
|
+
const preset = config2.get("editorConfig").options.preset;
|
|
602
|
+
if (preset === "default") {
|
|
483
603
|
content += "indent_style = space\nindent_size = 2\n";
|
|
484
|
-
} else if (
|
|
604
|
+
} else if (preset === "spaces4") {
|
|
485
605
|
content += "indent_style = space\nindent_size = 4\n";
|
|
486
|
-
} else if (
|
|
606
|
+
} else if (preset === "tabs") {
|
|
487
607
|
content += "indent_style = tab\n";
|
|
488
608
|
}
|
|
489
609
|
await fs7.outputFile(".editorconfig", content);
|
|
@@ -492,70 +612,71 @@ var init_editor_config = __esm({
|
|
|
492
612
|
"src/services/editor-config.ts"() {
|
|
493
613
|
"use strict";
|
|
494
614
|
init_esm_shims();
|
|
615
|
+
init_options();
|
|
616
|
+
init_handle_cancel();
|
|
495
617
|
}
|
|
496
618
|
});
|
|
497
619
|
|
|
498
620
|
// src/services/license.ts
|
|
499
|
-
import { text as text3, select as
|
|
621
|
+
import { text as text3, select as select7, log as log8 } from "@clack/prompts";
|
|
500
622
|
import fs8 from "fs-extra";
|
|
501
623
|
import path3 from "path";
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
624
|
+
import pc8 from "picocolors";
|
|
625
|
+
async function promptLicense(config2) {
|
|
626
|
+
log8.message(pc8.bgGreen(pc8.black(" License Configuration ")));
|
|
627
|
+
const licenseOptions = config2.get("license").options;
|
|
628
|
+
licenseOptions.name = await withCancelHandling(
|
|
629
|
+
async () => text3({
|
|
630
|
+
message: "License Holder Name:",
|
|
631
|
+
placeholder: "John Doe",
|
|
632
|
+
initialValue: licenseOptions.name
|
|
633
|
+
})
|
|
634
|
+
);
|
|
635
|
+
licenseOptions.email = await withCancelHandling(
|
|
636
|
+
async () => text3({
|
|
637
|
+
message: "License Holder Email:",
|
|
638
|
+
placeholder: "john@example.com",
|
|
639
|
+
initialValue: licenseOptions.email
|
|
640
|
+
})
|
|
641
|
+
);
|
|
642
|
+
licenseOptions.website = await withCancelHandling(
|
|
643
|
+
async () => text3({
|
|
644
|
+
message: "License Holder Website:",
|
|
645
|
+
placeholder: "https://example.com",
|
|
646
|
+
initialValue: licenseOptions.website
|
|
647
|
+
})
|
|
648
|
+
);
|
|
649
|
+
licenseOptions.type = await withCancelHandling(
|
|
650
|
+
async () => select7({
|
|
651
|
+
message: "Select License Type:",
|
|
652
|
+
options: LICENSE_TYPE_OPTIONS
|
|
653
|
+
})
|
|
654
|
+
);
|
|
529
655
|
}
|
|
530
|
-
async function installLicense(
|
|
531
|
-
|
|
656
|
+
async function installLicense(config2) {
|
|
657
|
+
const licenseOptions = config2.get("license").options;
|
|
658
|
+
const { type, name, email, website } = licenseOptions;
|
|
659
|
+
if (type !== "UNLICENSED") {
|
|
532
660
|
const year = (/* @__PURE__ */ new Date()).getFullYear().toString();
|
|
533
|
-
const templatePath = path3.join(
|
|
534
|
-
__dirname,
|
|
535
|
-
"licenses",
|
|
536
|
-
`${config.licenseType}.txt`
|
|
537
|
-
);
|
|
661
|
+
const templatePath = path3.join(__dirname, "licenses", `${type}.txt`);
|
|
538
662
|
if (await fs8.pathExists(templatePath)) {
|
|
539
663
|
let licenseContent = await fs8.readFile(templatePath, "utf-8");
|
|
540
664
|
licenseContent = licenseContent.replace(/{YEAR}/g, year);
|
|
541
|
-
licenseContent = licenseContent.replace(/{HOLDER}/g,
|
|
542
|
-
licenseContent = licenseContent.replace(/{EMAIL}/g,
|
|
543
|
-
licenseContent = licenseContent.replace(
|
|
544
|
-
/{WEBSITE}/g,
|
|
545
|
-
config.licenseWebsite
|
|
546
|
-
);
|
|
665
|
+
licenseContent = licenseContent.replace(/{HOLDER}/g, name || "");
|
|
666
|
+
licenseContent = licenseContent.replace(/{EMAIL}/g, email || "");
|
|
667
|
+
licenseContent = licenseContent.replace(/{WEBSITE}/g, website || "");
|
|
547
668
|
await fs8.outputFile("LICENSE", licenseContent);
|
|
548
669
|
} else {
|
|
549
|
-
const simpleContent = `Copyright (c) ${year} ${
|
|
550
|
-
Licensed under ${
|
|
670
|
+
const simpleContent = `Copyright (c) ${year} ${name}
|
|
671
|
+
Licensed under ${type}`;
|
|
551
672
|
await fs8.outputFile("LICENSE", simpleContent);
|
|
552
673
|
}
|
|
553
674
|
}
|
|
554
675
|
if (await fs8.pathExists("package.json")) {
|
|
555
676
|
const pkg = await fs8.readJson("package.json");
|
|
556
|
-
pkg.license =
|
|
557
|
-
if (
|
|
558
|
-
pkg.author =
|
|
677
|
+
pkg.license = type;
|
|
678
|
+
if (name) {
|
|
679
|
+
pkg.author = { name, email, url: website };
|
|
559
680
|
}
|
|
560
681
|
await fs8.writeJson("package.json", pkg, { spaces: 2 });
|
|
561
682
|
}
|
|
@@ -564,6 +685,215 @@ var init_license = __esm({
|
|
|
564
685
|
"src/services/license.ts"() {
|
|
565
686
|
"use strict";
|
|
566
687
|
init_esm_shims();
|
|
688
|
+
init_options();
|
|
689
|
+
init_handle_cancel();
|
|
690
|
+
}
|
|
691
|
+
});
|
|
692
|
+
|
|
693
|
+
// src/config/config.ts
|
|
694
|
+
import pc9 from "picocolors";
|
|
695
|
+
var Config, config;
|
|
696
|
+
var init_config = __esm({
|
|
697
|
+
"src/config/config.ts"() {
|
|
698
|
+
"use strict";
|
|
699
|
+
init_esm_shims();
|
|
700
|
+
Config = class {
|
|
701
|
+
data;
|
|
702
|
+
constructor() {
|
|
703
|
+
this.data = {
|
|
704
|
+
husky: {
|
|
705
|
+
selected: false,
|
|
706
|
+
options: { hookType: "none", customScript: "npm run test" }
|
|
707
|
+
},
|
|
708
|
+
formatter: {
|
|
709
|
+
selected: false,
|
|
710
|
+
options: { choice: "prettier" }
|
|
711
|
+
},
|
|
712
|
+
linter: {
|
|
713
|
+
selected: false,
|
|
714
|
+
options: { choice: "eslint" }
|
|
715
|
+
},
|
|
716
|
+
lintStaged: {
|
|
717
|
+
selected: false,
|
|
718
|
+
options: { lintExtensions: [], formatExtensions: [] }
|
|
719
|
+
},
|
|
720
|
+
env: {
|
|
721
|
+
selected: false,
|
|
722
|
+
options: {
|
|
723
|
+
variant: "@t3-oss/env-nextjs",
|
|
724
|
+
validator: "zod",
|
|
725
|
+
installPresets: false,
|
|
726
|
+
presets: [],
|
|
727
|
+
split: "split",
|
|
728
|
+
location: "src/env"
|
|
729
|
+
}
|
|
730
|
+
},
|
|
731
|
+
test: {
|
|
732
|
+
selected: false,
|
|
733
|
+
options: { runner: "vitest" }
|
|
734
|
+
},
|
|
735
|
+
editorConfig: {
|
|
736
|
+
selected: false,
|
|
737
|
+
options: { preset: "default" }
|
|
738
|
+
},
|
|
739
|
+
license: {
|
|
740
|
+
selected: false,
|
|
741
|
+
options: { name: "", email: "", website: "", type: "MIT" }
|
|
742
|
+
}
|
|
743
|
+
};
|
|
744
|
+
}
|
|
745
|
+
get(tool) {
|
|
746
|
+
return this.data[tool];
|
|
747
|
+
}
|
|
748
|
+
enableTool(tool) {
|
|
749
|
+
this.data[tool].selected = true;
|
|
750
|
+
}
|
|
751
|
+
get summary() {
|
|
752
|
+
const lines = [];
|
|
753
|
+
lines.push(pc9.bold("The following actions will be performed:"));
|
|
754
|
+
lines.push("");
|
|
755
|
+
if (this.data.husky.selected) {
|
|
756
|
+
lines.push(pc9.magenta(`\u2022 Install and configure Husky`));
|
|
757
|
+
if (this.data.husky.options.hookType === "custom") {
|
|
758
|
+
lines.push(pc9.dim(` - Custom hook script`));
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
if (this.data.formatter.selected) {
|
|
762
|
+
const choice = this.data.formatter.options.choice;
|
|
763
|
+
lines.push(pc9.blue(`\u2022 Install and configure ${choice || "Formatter"}`));
|
|
764
|
+
}
|
|
765
|
+
if (this.data.linter.selected) {
|
|
766
|
+
const choice = this.data.linter.options.choice;
|
|
767
|
+
lines.push(pc9.yellow(`\u2022 Install and configure ${choice || "Linter"}`));
|
|
768
|
+
}
|
|
769
|
+
if (this.data.lintStaged.selected) {
|
|
770
|
+
lines.push(pc9.green(`\u2022 Install and configure Lint-staged`));
|
|
771
|
+
const lintExts = this.data.lintStaged.options.lintExtensions.join(", ");
|
|
772
|
+
const formatExts = this.data.lintStaged.options.formatExtensions.join(", ");
|
|
773
|
+
if (lintExts) lines.push(pc9.dim(` - Lint: ${lintExts}`));
|
|
774
|
+
if (formatExts) lines.push(pc9.dim(` - Format: ${formatExts}`));
|
|
775
|
+
}
|
|
776
|
+
if (this.data.env.selected) {
|
|
777
|
+
lines.push(pc9.cyan(`\u2022 Install and configure Env Validation`));
|
|
778
|
+
lines.push(pc9.dim(` - Variant: ${this.data.env.options.variant}`));
|
|
779
|
+
lines.push(pc9.dim(` - Validator: ${this.data.env.options.validator}`));
|
|
780
|
+
}
|
|
781
|
+
if (this.data.test.selected) {
|
|
782
|
+
const runner = this.data.test.options.runner;
|
|
783
|
+
lines.push(pc9.red(`\u2022 Install and configure Test Runner (${runner})`));
|
|
784
|
+
}
|
|
785
|
+
if (this.data.editorConfig.selected) {
|
|
786
|
+
const preset = this.data.editorConfig.options.preset;
|
|
787
|
+
lines.push(pc9.white(`\u2022 Create .editorconfig (${preset})`));
|
|
788
|
+
}
|
|
789
|
+
if (this.data.license.selected) {
|
|
790
|
+
const type = this.data.license.options.type;
|
|
791
|
+
const name = this.data.license.options.name;
|
|
792
|
+
lines.push(pc9.green(`\u2022 Create LICENSE (${type})`));
|
|
793
|
+
lines.push(pc9.dim(` - Holder: ${name}`));
|
|
794
|
+
}
|
|
795
|
+
return lines.join("\n");
|
|
796
|
+
}
|
|
797
|
+
};
|
|
798
|
+
config = new Config();
|
|
799
|
+
}
|
|
800
|
+
});
|
|
801
|
+
|
|
802
|
+
// src/steps/execution.ts
|
|
803
|
+
import { spinner } from "@clack/prompts";
|
|
804
|
+
async function execution(config2) {
|
|
805
|
+
const s = spinner();
|
|
806
|
+
if (config2.get("husky").selected) {
|
|
807
|
+
s.start("Setting up Husky...");
|
|
808
|
+
await installHusky(config2);
|
|
809
|
+
s.stop("Husky setup complete.");
|
|
810
|
+
}
|
|
811
|
+
if (config2.get("formatter").selected) {
|
|
812
|
+
const choice = config2.get("formatter").options.choice;
|
|
813
|
+
s.start(`Setting up ${choice}...`);
|
|
814
|
+
await installFormatter(config2);
|
|
815
|
+
s.stop(`${choice} setup complete.`);
|
|
816
|
+
}
|
|
817
|
+
if (config2.get("linter").selected) {
|
|
818
|
+
const choice = config2.get("linter").options.choice;
|
|
819
|
+
s.start(`Setting up ${choice}...`);
|
|
820
|
+
await installLinter(config2);
|
|
821
|
+
s.stop(`${choice} setup complete.`);
|
|
822
|
+
}
|
|
823
|
+
if (config2.get("lintStaged").selected) {
|
|
824
|
+
s.start("Setting up Lint-staged...");
|
|
825
|
+
await installLintStaged(config2);
|
|
826
|
+
s.stop("Lint-staged setup complete.");
|
|
827
|
+
}
|
|
828
|
+
if (config2.get("env").selected) {
|
|
829
|
+
s.start("Setting up Env Validation...");
|
|
830
|
+
await installEnv(config2);
|
|
831
|
+
s.stop("Env Validation setup complete.");
|
|
832
|
+
}
|
|
833
|
+
if (config2.get("test").selected) {
|
|
834
|
+
const runner = config2.get("test").options.runner;
|
|
835
|
+
s.start(`Setting up ${runner}...`);
|
|
836
|
+
await installTest(config2);
|
|
837
|
+
s.stop(`${runner} setup complete.`);
|
|
838
|
+
}
|
|
839
|
+
if (config2.get("editorConfig").selected) {
|
|
840
|
+
s.start("Creating .editorconfig...");
|
|
841
|
+
await installEditorConfig(config2);
|
|
842
|
+
s.stop(".editorconfig created.");
|
|
843
|
+
}
|
|
844
|
+
if (config2.get("license").selected) {
|
|
845
|
+
s.start("Creating LICENSE...");
|
|
846
|
+
await installLicense(config2);
|
|
847
|
+
s.stop("LICENSE created.");
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
var init_execution = __esm({
|
|
851
|
+
"src/steps/execution.ts"() {
|
|
852
|
+
"use strict";
|
|
853
|
+
init_esm_shims();
|
|
854
|
+
init_husky();
|
|
855
|
+
init_formatter();
|
|
856
|
+
init_linter();
|
|
857
|
+
init_lint_staged();
|
|
858
|
+
init_env();
|
|
859
|
+
init_test();
|
|
860
|
+
init_editor_config();
|
|
861
|
+
init_license();
|
|
862
|
+
}
|
|
863
|
+
});
|
|
864
|
+
|
|
865
|
+
// src/utils/logger.ts
|
|
866
|
+
import fs9 from "fs-extra";
|
|
867
|
+
import path4 from "path";
|
|
868
|
+
async function logError(error) {
|
|
869
|
+
try {
|
|
870
|
+
await fs9.ensureDir(ERRORS_DIR);
|
|
871
|
+
const gitignorePath = path4.join(LOG_DIR, ".gitignore");
|
|
872
|
+
if (!await fs9.pathExists(gitignorePath)) {
|
|
873
|
+
await fs9.outputFile(gitignorePath, "*\n");
|
|
874
|
+
}
|
|
875
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
876
|
+
const logFile = path4.join(ERRORS_DIR, `log-${timestamp}.txt`);
|
|
877
|
+
const errorMessage = error instanceof Error ? error.stack || error.message : String(error);
|
|
878
|
+
const logContent = `Timestamp: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
879
|
+
|
|
880
|
+
Error:
|
|
881
|
+
${errorMessage}
|
|
882
|
+
`;
|
|
883
|
+
await fs9.outputFile(logFile, logContent);
|
|
884
|
+
return logFile;
|
|
885
|
+
} catch (e) {
|
|
886
|
+
console.error("Failed to log error:", e);
|
|
887
|
+
return "";
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
var LOG_DIR, ERRORS_DIR;
|
|
891
|
+
var init_logger = __esm({
|
|
892
|
+
"src/utils/logger.ts"() {
|
|
893
|
+
"use strict";
|
|
894
|
+
init_esm_shims();
|
|
895
|
+
LOG_DIR = ".mayrlabs/setup-project";
|
|
896
|
+
ERRORS_DIR = path4.join(LOG_DIR, "errors");
|
|
567
897
|
}
|
|
568
898
|
});
|
|
569
899
|
|
|
@@ -596,13 +926,47 @@ var init_git = __esm({
|
|
|
596
926
|
}
|
|
597
927
|
});
|
|
598
928
|
|
|
929
|
+
// src/steps/git-check.ts
|
|
930
|
+
import { confirm as confirm3, spinner as spinner2, text as text4 } from "@clack/prompts";
|
|
931
|
+
async function gitCheck() {
|
|
932
|
+
if (await isGitRepository()) {
|
|
933
|
+
if (await isGitDirty()) {
|
|
934
|
+
const shouldCommit = await confirm3({
|
|
935
|
+
message: "Your working directory is dirty. Would you like to commit changes before proceeding?"
|
|
936
|
+
});
|
|
937
|
+
if (shouldCommit) {
|
|
938
|
+
const message = await text4({
|
|
939
|
+
message: "Enter commit message:",
|
|
940
|
+
placeholder: "wip: pre-setup commit",
|
|
941
|
+
validate(value) {
|
|
942
|
+
if (value.length === 0) return "Commit message is required";
|
|
943
|
+
}
|
|
944
|
+
});
|
|
945
|
+
if (typeof message === "string") {
|
|
946
|
+
const s = spinner2();
|
|
947
|
+
s.start("Committing changes...");
|
|
948
|
+
await commitChanges(message);
|
|
949
|
+
s.stop("Changes committed.");
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
var init_git_check = __esm({
|
|
956
|
+
"src/steps/git-check.ts"() {
|
|
957
|
+
"use strict";
|
|
958
|
+
init_esm_shims();
|
|
959
|
+
init_git();
|
|
960
|
+
}
|
|
961
|
+
});
|
|
962
|
+
|
|
599
963
|
// package.json
|
|
600
964
|
var package_default;
|
|
601
965
|
var init_package = __esm({
|
|
602
966
|
"package.json"() {
|
|
603
967
|
package_default = {
|
|
604
968
|
name: "@mayrlabs/setup-project",
|
|
605
|
-
version: "0.1.
|
|
969
|
+
version: "0.1.6",
|
|
606
970
|
description: "Interactive CLI to setup project tools",
|
|
607
971
|
private: false,
|
|
608
972
|
publishConfig: {
|
|
@@ -651,67 +1015,89 @@ var init_package = __esm({
|
|
|
651
1015
|
"@clack/prompts": "^0.7.0",
|
|
652
1016
|
commander: "^11.1.0",
|
|
653
1017
|
execa: "^8.0.1",
|
|
1018
|
+
figlet: "^1.10.0",
|
|
654
1019
|
"fs-extra": "^11.2.0",
|
|
655
1020
|
picocolors: "^1.0.0",
|
|
656
1021
|
zod: "^3.22.4"
|
|
657
1022
|
},
|
|
658
1023
|
devDependencies: {
|
|
1024
|
+
"@types/figlet": "^1.7.0",
|
|
659
1025
|
"@types/fs-extra": "^11.0.4",
|
|
660
1026
|
"@types/node": "^20.11.16",
|
|
661
1027
|
tsup: "^8.5.1",
|
|
1028
|
+
tsx: "^4.21.0",
|
|
662
1029
|
typescript: "^5.3.3"
|
|
663
1030
|
}
|
|
664
1031
|
};
|
|
665
1032
|
}
|
|
666
1033
|
});
|
|
667
1034
|
|
|
668
|
-
// src/utils/
|
|
669
|
-
import
|
|
670
|
-
import
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
${
|
|
685
|
-
|
|
686
|
-
await fs9.outputFile(logFile, logContent);
|
|
687
|
-
return logFile;
|
|
688
|
-
} catch (e) {
|
|
689
|
-
console.error("Failed to log error:", e);
|
|
690
|
-
return "";
|
|
691
|
-
}
|
|
1035
|
+
// src/utils/display.ts
|
|
1036
|
+
import pc10 from "picocolors";
|
|
1037
|
+
import figlet from "figlet";
|
|
1038
|
+
function introScreen() {
|
|
1039
|
+
console.log();
|
|
1040
|
+
console.log(
|
|
1041
|
+
pc10.cyan(
|
|
1042
|
+
figlet.textSync("MayR\nLabs", {
|
|
1043
|
+
font: "Graceful",
|
|
1044
|
+
horizontalLayout: "default",
|
|
1045
|
+
verticalLayout: "default",
|
|
1046
|
+
width: 80,
|
|
1047
|
+
whitespaceBreak: true
|
|
1048
|
+
})
|
|
1049
|
+
)
|
|
1050
|
+
);
|
|
1051
|
+
console.log(pc10.cyan(`@mayrlabs/setup-project v${package_default.version}`));
|
|
1052
|
+
console.log();
|
|
692
1053
|
}
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
1054
|
+
function showAbout() {
|
|
1055
|
+
introScreen();
|
|
1056
|
+
console.log(pc10.bold("About:"));
|
|
1057
|
+
console.log(
|
|
1058
|
+
" Interactive CLI to setup project tools like Husky, Prettier, ESLint, etc."
|
|
1059
|
+
);
|
|
1060
|
+
console.log("");
|
|
1061
|
+
console.log(pc10.bold("How to use:"));
|
|
1062
|
+
console.log(
|
|
1063
|
+
" Run 'npx @mayrlabs/setup-project' and follow the interactive prompts."
|
|
1064
|
+
);
|
|
1065
|
+
console.log("");
|
|
1066
|
+
}
|
|
1067
|
+
function showVisit() {
|
|
1068
|
+
console.log(pc10.bold("Project Homepage:"));
|
|
1069
|
+
console.log(pc10.underline(pc10.cyan(package_default.homepage)));
|
|
1070
|
+
console.log("");
|
|
1071
|
+
}
|
|
1072
|
+
function showManual() {
|
|
1073
|
+
introScreen();
|
|
1074
|
+
console.log(pc10.bold("Usage:"));
|
|
1075
|
+
console.log(" npx @mayrlabs/setup-project [command] [options]");
|
|
1076
|
+
console.log("");
|
|
1077
|
+
console.log(pc10.bold("Commands:"));
|
|
1078
|
+
console.log(" about Show project details");
|
|
1079
|
+
console.log(" version Show version information");
|
|
1080
|
+
console.log(" visit Visit project homepage");
|
|
1081
|
+
console.log(" help Show this help message");
|
|
1082
|
+
console.log("");
|
|
1083
|
+
console.log(pc10.bold("Options:"));
|
|
1084
|
+
console.log(" -a, --about Show project details");
|
|
1085
|
+
console.log(" -v, --version Show version information");
|
|
1086
|
+
console.log(" -V, --visit Visit project homepage");
|
|
1087
|
+
console.log(" -h, --help Show this help message");
|
|
1088
|
+
console.log("");
|
|
1089
|
+
}
|
|
1090
|
+
var init_display = __esm({
|
|
1091
|
+
"src/utils/display.ts"() {
|
|
696
1092
|
"use strict";
|
|
697
1093
|
init_esm_shims();
|
|
698
|
-
|
|
699
|
-
ERRORS_DIR = path4.join(LOG_DIR, "errors");
|
|
1094
|
+
init_package();
|
|
700
1095
|
}
|
|
701
1096
|
});
|
|
702
1097
|
|
|
703
1098
|
// src/index.ts
|
|
704
|
-
import {
|
|
705
|
-
|
|
706
|
-
outro,
|
|
707
|
-
multiselect as multiselect3,
|
|
708
|
-
isCancel,
|
|
709
|
-
cancel,
|
|
710
|
-
note,
|
|
711
|
-
confirm as confirm2,
|
|
712
|
-
spinner
|
|
713
|
-
} from "@clack/prompts";
|
|
714
|
-
import pc from "picocolors";
|
|
1099
|
+
import { outro, multiselect as multiselect3, note, confirm as confirm4, intro } from "@clack/prompts";
|
|
1100
|
+
import pc11 from "picocolors";
|
|
715
1101
|
import { program } from "commander";
|
|
716
1102
|
var require_index = __commonJS({
|
|
717
1103
|
"src/index.ts"() {
|
|
@@ -724,148 +1110,93 @@ var require_index = __commonJS({
|
|
|
724
1110
|
init_test();
|
|
725
1111
|
init_editor_config();
|
|
726
1112
|
init_license();
|
|
727
|
-
|
|
728
|
-
|
|
1113
|
+
init_config();
|
|
1114
|
+
init_handle_cancel();
|
|
1115
|
+
init_options();
|
|
1116
|
+
init_execution();
|
|
729
1117
|
init_logger();
|
|
1118
|
+
init_git_check();
|
|
1119
|
+
init_display();
|
|
730
1120
|
async function main() {
|
|
731
1121
|
try {
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
{ value: "formatter", label: "Formatter (Prettier/Oxfmt)" },
|
|
762
|
-
{ value: "linter", label: "Linter (Eslint/Oxlint)" },
|
|
763
|
-
{ value: "lint-staged", label: "Lint-staged" },
|
|
764
|
-
{ value: "env", label: "Env Validation (@t3-oss/env)" },
|
|
765
|
-
{ value: "test", label: "Test Runner (Vitest/Jest)" },
|
|
766
|
-
{ value: "editorConfig", label: "EditorConfig" },
|
|
767
|
-
{ value: "license", label: "License" }
|
|
768
|
-
],
|
|
769
|
-
required: false
|
|
770
|
-
});
|
|
771
|
-
if (isCancel(tools)) {
|
|
772
|
-
cancel("Operation cancelled.");
|
|
773
|
-
process.exit(0);
|
|
774
|
-
}
|
|
775
|
-
const selectedTools = tools;
|
|
776
|
-
const config = {
|
|
777
|
-
husky: selectedTools.includes("husky"),
|
|
778
|
-
formatter: selectedTools.includes("formatter"),
|
|
779
|
-
linter: selectedTools.includes("linter"),
|
|
780
|
-
lintStaged: selectedTools.includes("lint-staged"),
|
|
781
|
-
env: selectedTools.includes("env"),
|
|
782
|
-
test: selectedTools.includes("test"),
|
|
783
|
-
editorConfig: selectedTools.includes("editorConfig"),
|
|
784
|
-
license: selectedTools.includes("license")
|
|
785
|
-
};
|
|
786
|
-
if (config.husky) await promptHusky(config);
|
|
787
|
-
if (config.formatter) await promptFormatter(config);
|
|
788
|
-
if (config.linter) await promptLinter(config);
|
|
789
|
-
if (config.lintStaged) await promptLintStaged(config);
|
|
790
|
-
if (config.env) await promptEnv(config);
|
|
791
|
-
if (config.test) await promptTest(config);
|
|
792
|
-
if (config.editorConfig) await promptEditorConfig(config);
|
|
793
|
-
if (config.license) await promptLicense(config);
|
|
794
|
-
let summary = "The following actions will be performed:\n\n";
|
|
795
|
-
if (config.husky) summary += "- Install and configure Husky\n";
|
|
796
|
-
if (config.formatter)
|
|
797
|
-
summary += `- Install and configure ${config.formatterChoice}
|
|
798
|
-
`;
|
|
799
|
-
if (config.linter)
|
|
800
|
-
summary += `- Install and configure ${config.linterChoice}
|
|
801
|
-
`;
|
|
802
|
-
if (config.lintStaged) summary += "- Install and configure Lint-staged\n";
|
|
803
|
-
if (config.env) summary += "- Install and configure @t3-oss/env\n";
|
|
804
|
-
if (config.test)
|
|
805
|
-
summary += `- Install and configure ${config.testRunner}
|
|
806
|
-
`;
|
|
807
|
-
if (config.editorConfig) summary += "- Create .editorconfig\n";
|
|
808
|
-
if (config.license) summary += `- Create LICENSE (${config.licenseType})
|
|
809
|
-
`;
|
|
810
|
-
note(summary, "Configuration Summary");
|
|
811
|
-
const proceed = await confirm2({
|
|
812
|
-
message: "Do you want to proceed with the installation?"
|
|
813
|
-
});
|
|
814
|
-
if (!proceed || isCancel(proceed)) {
|
|
815
|
-
cancel("Installation cancelled. Configuration saved.");
|
|
1122
|
+
introScreen();
|
|
1123
|
+
intro(
|
|
1124
|
+
pc11.inverse(pc11.bold(pc11.cyan(" Welcome to the Project Setup Wizard ")))
|
|
1125
|
+
);
|
|
1126
|
+
await gitCheck();
|
|
1127
|
+
const tools = await withCancelHandling(
|
|
1128
|
+
async () => multiselect3({
|
|
1129
|
+
message: "Select tools to configure:",
|
|
1130
|
+
options: TOOL_OPTIONS,
|
|
1131
|
+
required: false
|
|
1132
|
+
})
|
|
1133
|
+
);
|
|
1134
|
+
tools.forEach((tool) => config.enableTool(tool));
|
|
1135
|
+
if (config.get("husky").selected) await promptHusky(config);
|
|
1136
|
+
if (config.get("formatter").selected) await promptFormatter(config);
|
|
1137
|
+
if (config.get("linter").selected) await promptLinter(config);
|
|
1138
|
+
if (config.get("lintStaged").selected) await promptLintStaged(config);
|
|
1139
|
+
if (config.get("env").selected) await promptEnv(config);
|
|
1140
|
+
if (config.get("test").selected) await promptTest(config);
|
|
1141
|
+
if (config.get("editorConfig").selected) await promptEditorConfig(config);
|
|
1142
|
+
if (config.get("license").selected) await promptLicense(config);
|
|
1143
|
+
note(config.summary, "Configuration Summary");
|
|
1144
|
+
const proceed = await withCancelHandling(
|
|
1145
|
+
async () => confirm4({
|
|
1146
|
+
message: "Do you want to proceed with the installation?"
|
|
1147
|
+
})
|
|
1148
|
+
);
|
|
1149
|
+
if (!proceed) {
|
|
1150
|
+
outro(pc11.yellow("Installation cancelled."));
|
|
816
1151
|
process.exit(0);
|
|
817
1152
|
}
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
s.start("Setting up Husky...");
|
|
821
|
-
await installHusky(config);
|
|
822
|
-
s.stop("Husky setup complete.");
|
|
823
|
-
}
|
|
824
|
-
if (config.formatter) {
|
|
825
|
-
s.start(`Setting up ${config.formatterChoice}...`);
|
|
826
|
-
await installFormatter(config);
|
|
827
|
-
s.stop(`${config.formatterChoice} setup complete.`);
|
|
828
|
-
}
|
|
829
|
-
if (config.linter) {
|
|
830
|
-
s.start(`Setting up ${config.linterChoice}...`);
|
|
831
|
-
await installLinter(config);
|
|
832
|
-
s.stop(`${config.linterChoice} setup complete.`);
|
|
833
|
-
}
|
|
834
|
-
if (config.lintStaged) {
|
|
835
|
-
s.start("Setting up Lint-staged...");
|
|
836
|
-
await installLintStaged(config);
|
|
837
|
-
s.stop("Lint-staged setup complete.");
|
|
838
|
-
}
|
|
839
|
-
if (config.env) {
|
|
840
|
-
s.start("Setting up Env Validation...");
|
|
841
|
-
await installEnv(config);
|
|
842
|
-
s.stop("Env Validation setup complete.");
|
|
843
|
-
}
|
|
844
|
-
if (config.test) {
|
|
845
|
-
s.start(`Setting up ${config.testRunner}...`);
|
|
846
|
-
await installTest(config);
|
|
847
|
-
s.stop(`${config.testRunner} setup complete.`);
|
|
848
|
-
}
|
|
849
|
-
if (config.editorConfig) {
|
|
850
|
-
s.start("Creating .editorconfig...");
|
|
851
|
-
await installEditorConfig(config);
|
|
852
|
-
s.stop(".editorconfig created.");
|
|
853
|
-
}
|
|
854
|
-
if (config.license) {
|
|
855
|
-
s.start("Creating LICENSE...");
|
|
856
|
-
await installLicense(config);
|
|
857
|
-
s.stop("LICENSE created.");
|
|
858
|
-
}
|
|
859
|
-
outro(pc.green("Setup complete!"));
|
|
1153
|
+
await execution(config);
|
|
1154
|
+
outro(pc11.green("Setup complete!"));
|
|
860
1155
|
} catch (error) {
|
|
861
1156
|
const logPath = await logError(error);
|
|
862
|
-
outro(
|
|
1157
|
+
outro(pc11.red(`
|
|
863
1158
|
Something went wrong!
|
|
864
1159
|
Error log saved to: ${logPath}`));
|
|
865
1160
|
process.exit(1);
|
|
866
1161
|
}
|
|
867
1162
|
}
|
|
868
|
-
program.
|
|
1163
|
+
program.helpOption(false);
|
|
1164
|
+
program.name("setup-project").description("Interactive setup for common project tools").option("-a, --about", "Show project details").option("-v, --version", "Show version info").option("-V, --visit", "Visit project homepage").option("-h, --help", "Show help");
|
|
1165
|
+
program.command("about").action(() => {
|
|
1166
|
+
showAbout();
|
|
1167
|
+
process.exit(0);
|
|
1168
|
+
});
|
|
1169
|
+
program.command("version").action(() => {
|
|
1170
|
+
introScreen();
|
|
1171
|
+
process.exit(0);
|
|
1172
|
+
});
|
|
1173
|
+
program.command("visit").action(() => {
|
|
1174
|
+
showVisit();
|
|
1175
|
+
process.exit(0);
|
|
1176
|
+
});
|
|
1177
|
+
program.command("help").action(() => {
|
|
1178
|
+
showManual();
|
|
1179
|
+
process.exit(0);
|
|
1180
|
+
});
|
|
1181
|
+
program.action(async (options) => {
|
|
1182
|
+
if (options.about) {
|
|
1183
|
+
showAbout();
|
|
1184
|
+
process.exit(0);
|
|
1185
|
+
}
|
|
1186
|
+
if (options.version) {
|
|
1187
|
+
introScreen();
|
|
1188
|
+
process.exit(0);
|
|
1189
|
+
}
|
|
1190
|
+
if (options.visit) {
|
|
1191
|
+
showVisit();
|
|
1192
|
+
process.exit(0);
|
|
1193
|
+
}
|
|
1194
|
+
if (options.help) {
|
|
1195
|
+
showManual();
|
|
1196
|
+
process.exit(0);
|
|
1197
|
+
}
|
|
1198
|
+
await main();
|
|
1199
|
+
});
|
|
869
1200
|
program.parse();
|
|
870
1201
|
}
|
|
871
1202
|
});
|