@mayrlabs/setup-project 0.1.3 → 0.1.5
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/LICENSE +21 -0
- package/README.md +18 -47
- package/dist/index.js +755 -271
- package/dist/index.mjs +872 -282
- package/dist/licenses/Apache-2.0.txt +190 -0
- package/dist/licenses/ISC.txt +15 -0
- package/dist/licenses/MIT.txt +21 -0
- package/package.json +9 -2
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -16,6 +16,19 @@ var __commonJS = (cb, mod) => function __require() {
|
|
|
16
16
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
+
// node_modules/tsup/assets/esm_shims.js
|
|
20
|
+
import path from "path";
|
|
21
|
+
import { fileURLToPath } from "url";
|
|
22
|
+
var getFilename, getDirname, __dirname;
|
|
23
|
+
var init_esm_shims = __esm({
|
|
24
|
+
"node_modules/tsup/assets/esm_shims.js"() {
|
|
25
|
+
"use strict";
|
|
26
|
+
getFilename = () => fileURLToPath(import.meta.url);
|
|
27
|
+
getDirname = () => path.dirname(getFilename());
|
|
28
|
+
__dirname = /* @__PURE__ */ getDirname();
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
19
32
|
// src/utils/pm.ts
|
|
20
33
|
import { execa } from "execa";
|
|
21
34
|
async function getPackageManager() {
|
|
@@ -48,37 +61,156 @@ async function installPackages(packages, dev = false) {
|
|
|
48
61
|
var init_pm = __esm({
|
|
49
62
|
"src/utils/pm.ts"() {
|
|
50
63
|
"use strict";
|
|
64
|
+
init_esm_shims();
|
|
51
65
|
}
|
|
52
66
|
});
|
|
53
67
|
|
|
54
|
-
// src/
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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 = [
|
|
62
85
|
{ value: "lint-staged", label: "lint-staged" },
|
|
63
86
|
{ value: "custom", label: "Custom script" },
|
|
64
87
|
{ value: "none", label: "None" }
|
|
65
|
-
]
|
|
66
|
-
|
|
67
|
-
|
|
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 };
|
|
68
198
|
if (hookType === "lint-staged") {
|
|
69
|
-
|
|
199
|
+
config2.enableTool("lintStaged");
|
|
70
200
|
} else if (hookType === "custom") {
|
|
71
|
-
const script = await
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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;
|
|
79
211
|
}
|
|
80
212
|
}
|
|
81
|
-
async function installHusky(
|
|
213
|
+
async function installHusky(config2) {
|
|
82
214
|
await installPackages(["husky"], true);
|
|
83
215
|
try {
|
|
84
216
|
await execa2("npx", ["husky", "init"]);
|
|
@@ -86,12 +218,15 @@ async function installHusky(config) {
|
|
|
86
218
|
await execa2("npm", ["pkg", "set", "scripts.prepare=husky"]);
|
|
87
219
|
await execa2("npm", ["run", "prepare"]);
|
|
88
220
|
}
|
|
89
|
-
|
|
221
|
+
const husky = config2.get("husky");
|
|
222
|
+
const hookType = husky.options.hookType;
|
|
223
|
+
const customScript = husky.options.customScript;
|
|
224
|
+
if (hookType === "lint-staged") {
|
|
90
225
|
await fs.outputFile(".husky/pre-commit", "npx lint-staged\n", {
|
|
91
226
|
mode: 493
|
|
92
227
|
});
|
|
93
|
-
} else if (
|
|
94
|
-
await fs.outputFile(".husky/pre-commit", `${
|
|
228
|
+
} else if (hookType === "custom" && customScript) {
|
|
229
|
+
await fs.outputFile(".husky/pre-commit", `${customScript}
|
|
95
230
|
`, {
|
|
96
231
|
mode: 493
|
|
97
232
|
});
|
|
@@ -100,27 +235,32 @@ async function installHusky(config) {
|
|
|
100
235
|
var init_husky = __esm({
|
|
101
236
|
"src/services/husky.ts"() {
|
|
102
237
|
"use strict";
|
|
238
|
+
init_esm_shims();
|
|
103
239
|
init_pm();
|
|
240
|
+
init_options();
|
|
241
|
+
init_handle_cancel();
|
|
104
242
|
}
|
|
105
243
|
});
|
|
106
244
|
|
|
107
245
|
// src/services/formatter.ts
|
|
108
|
-
import { select as select2 } from "@clack/prompts";
|
|
246
|
+
import { select as select2, log as log2 } from "@clack/prompts";
|
|
109
247
|
import fs2 from "fs-extra";
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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({
|
|
113
254
|
message: "Select a formatter:",
|
|
114
|
-
options:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
config.formatterChoice = formatter;
|
|
120
|
-
}
|
|
255
|
+
options: FORMATTER_OPTIONS,
|
|
256
|
+
initialValue: formatterConfig.options.choice
|
|
257
|
+
})
|
|
258
|
+
);
|
|
259
|
+
formatterConfig.options = { choice: formatter };
|
|
121
260
|
}
|
|
122
|
-
async function installFormatter(
|
|
123
|
-
|
|
261
|
+
async function installFormatter(config2) {
|
|
262
|
+
const choice = config2.get("formatter").options.choice;
|
|
263
|
+
if (choice === "prettier") {
|
|
124
264
|
await installPackages(["prettier"], true);
|
|
125
265
|
const configContent = {
|
|
126
266
|
semi: true,
|
|
@@ -130,34 +270,39 @@ async function installFormatter(config) {
|
|
|
130
270
|
tabWidth: 2
|
|
131
271
|
};
|
|
132
272
|
await fs2.writeJson(".prettierrc", configContent, { spaces: 2 });
|
|
133
|
-
} else if (
|
|
273
|
+
} else if (choice === "oxfmt") {
|
|
134
274
|
await installPackages(["oxfmt"], true);
|
|
135
275
|
}
|
|
136
276
|
}
|
|
137
277
|
var init_formatter = __esm({
|
|
138
278
|
"src/services/formatter.ts"() {
|
|
139
279
|
"use strict";
|
|
280
|
+
init_esm_shims();
|
|
140
281
|
init_pm();
|
|
282
|
+
init_options();
|
|
283
|
+
init_handle_cancel();
|
|
141
284
|
}
|
|
142
285
|
});
|
|
143
286
|
|
|
144
287
|
// src/services/linter.ts
|
|
145
|
-
import { select as select3 } from "@clack/prompts";
|
|
288
|
+
import { select as select3, log as log3 } from "@clack/prompts";
|
|
146
289
|
import fs3 from "fs-extra";
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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({
|
|
150
296
|
message: "Select a linter:",
|
|
151
|
-
options:
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
config.linterChoice = linter;
|
|
157
|
-
}
|
|
297
|
+
options: LINTER_OPTIONS,
|
|
298
|
+
initialValue: linterConfig.options.choice
|
|
299
|
+
})
|
|
300
|
+
);
|
|
301
|
+
linterConfig.options = { choice: linter };
|
|
158
302
|
}
|
|
159
|
-
async function installLinter(
|
|
160
|
-
|
|
303
|
+
async function installLinter(config2) {
|
|
304
|
+
const choice = config2.get("linter").options.choice;
|
|
305
|
+
if (choice === "eslint") {
|
|
161
306
|
await installPackages(["eslint"], true);
|
|
162
307
|
const configContent = {
|
|
163
308
|
extends: ["eslint:recommended"],
|
|
@@ -171,81 +316,72 @@ async function installLinter(config) {
|
|
|
171
316
|
}
|
|
172
317
|
};
|
|
173
318
|
await fs3.writeJson(".eslintrc.json", configContent, { spaces: 2 });
|
|
174
|
-
} else if (
|
|
319
|
+
} else if (choice === "oxlint") {
|
|
175
320
|
await installPackages(["oxlint"], true);
|
|
176
321
|
}
|
|
177
322
|
}
|
|
178
323
|
var init_linter = __esm({
|
|
179
324
|
"src/services/linter.ts"() {
|
|
180
325
|
"use strict";
|
|
326
|
+
init_esm_shims();
|
|
181
327
|
init_pm();
|
|
328
|
+
init_options();
|
|
329
|
+
init_handle_cancel();
|
|
182
330
|
}
|
|
183
331
|
});
|
|
184
332
|
|
|
185
333
|
// src/services/lint-staged.ts
|
|
186
|
-
import { multiselect } from "@clack/prompts";
|
|
334
|
+
import { multiselect, log as log4 } from "@clack/prompts";
|
|
187
335
|
import fs4 from "fs-extra";
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
{ value: "svelte", label: "svelte" }
|
|
217
|
-
],
|
|
218
|
-
required: false
|
|
219
|
-
});
|
|
220
|
-
config.lintStagedLintExtensions = lintExtensions;
|
|
221
|
-
config.lintStagedFormatExtensions = formatExtensions;
|
|
222
|
-
if (lintExtensions.length > 0 && !config.linterChoice) {
|
|
223
|
-
await promptLinter(config);
|
|
224
|
-
config.linter = true;
|
|
225
|
-
}
|
|
226
|
-
if (formatExtensions.length > 0 && !config.formatterChoice) {
|
|
227
|
-
await promptFormatter(config);
|
|
228
|
-
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");
|
|
229
364
|
}
|
|
230
365
|
}
|
|
231
|
-
async function installLintStaged(
|
|
366
|
+
async function installLintStaged(config2) {
|
|
232
367
|
await installPackages(["lint-staged"], true);
|
|
233
368
|
const lintStagedConfig = {};
|
|
234
|
-
const
|
|
235
|
-
const
|
|
369
|
+
const lintStagedOptions = config2.get("lintStaged").options;
|
|
370
|
+
const lintExts = lintStagedOptions?.lintExtensions || [];
|
|
371
|
+
const formatExts = lintStagedOptions?.formatExtensions || [];
|
|
236
372
|
if (lintExts.length > 0) {
|
|
237
|
-
await installLinter(
|
|
373
|
+
await installLinter(config2);
|
|
238
374
|
const glob = `*.{${lintExts.join(",")}}`;
|
|
239
|
-
if (
|
|
375
|
+
if (config2.get("linter").options.choice === "oxlint") {
|
|
240
376
|
lintStagedConfig[glob] = ["npx oxlint --fix"];
|
|
241
377
|
} else {
|
|
242
378
|
lintStagedConfig[glob] = ["eslint --fix"];
|
|
243
379
|
}
|
|
244
380
|
}
|
|
245
381
|
if (formatExts.length > 0) {
|
|
246
|
-
await installFormatter(
|
|
382
|
+
await installFormatter(config2);
|
|
247
383
|
const glob = `*.{${formatExts.join(",")}}`;
|
|
248
|
-
if (
|
|
384
|
+
if (config2.get("formatter").options.choice === "oxfmt") {
|
|
249
385
|
lintStagedConfig[glob] = ["npx oxfmt"];
|
|
250
386
|
} else {
|
|
251
387
|
lintStagedConfig[glob] = ["prettier --write"];
|
|
@@ -256,92 +392,85 @@ async function installLintStaged(config) {
|
|
|
256
392
|
var init_lint_staged = __esm({
|
|
257
393
|
"src/services/lint-staged.ts"() {
|
|
258
394
|
"use strict";
|
|
395
|
+
init_esm_shims();
|
|
259
396
|
init_pm();
|
|
260
397
|
init_formatter();
|
|
261
398
|
init_linter();
|
|
399
|
+
init_options();
|
|
400
|
+
init_handle_cancel();
|
|
262
401
|
}
|
|
263
402
|
});
|
|
264
403
|
|
|
265
404
|
// src/services/env.ts
|
|
266
|
-
import { select as
|
|
405
|
+
import { select as select4, confirm as confirm2, text as text2, multiselect as multiselect2, log as log5 } from "@clack/prompts";
|
|
267
406
|
import fs5 from "fs-extra";
|
|
268
|
-
import
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
});
|
|
291
|
-
config.envInstallPresets = installPresets;
|
|
407
|
+
import path2 from "path";
|
|
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;
|
|
292
429
|
if (installPresets) {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
{ value: "uploadThing", label: "UploadThing" },
|
|
301
|
-
{ value: "render", label: "Render" },
|
|
302
|
-
{ value: "railway", label: "Railway" },
|
|
303
|
-
{ value: "fly.io", label: "Fly.io" },
|
|
304
|
-
{ value: "upstashRedis", label: "Upstash Redis" },
|
|
305
|
-
{ value: "coolify", label: "Coolify" },
|
|
306
|
-
{ value: "vite", label: "Vite" },
|
|
307
|
-
{ value: "wxt", label: "WXT" }
|
|
308
|
-
],
|
|
309
|
-
required: false
|
|
310
|
-
});
|
|
311
|
-
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
|
+
);
|
|
312
437
|
}
|
|
313
|
-
const split = await
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
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
|
+
};
|
|
327
459
|
}
|
|
328
|
-
async function installEnv(
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
}
|
|
334
|
-
const targetDir = config.envLocation;
|
|
335
|
-
await fs5.ensureDir(targetDir);
|
|
336
|
-
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(", ")}
|
|
337
466
|
` : "";
|
|
338
|
-
const content = `import { createEnv } from "${
|
|
339
|
-
import { ${
|
|
467
|
+
const content = `import { createEnv } from "${variant}";
|
|
468
|
+
import { ${validator} } from "${validator}";
|
|
340
469
|
|
|
341
470
|
${presetImport}`;
|
|
342
|
-
if (
|
|
471
|
+
if (split === "split") {
|
|
343
472
|
await fs5.outputFile(
|
|
344
|
-
|
|
473
|
+
path2.join(location, "env/server.ts"),
|
|
345
474
|
`${content}
|
|
346
475
|
// Server env definition
|
|
347
476
|
export const env = createEnv({
|
|
@@ -352,7 +481,7 @@ export const env = createEnv({
|
|
|
352
481
|
});`
|
|
353
482
|
);
|
|
354
483
|
await fs5.outputFile(
|
|
355
|
-
|
|
484
|
+
path2.join(location, "env/client.ts"),
|
|
356
485
|
`${content}
|
|
357
486
|
// Client env definition
|
|
358
487
|
export const env = createEnv({
|
|
@@ -366,7 +495,7 @@ export const env = createEnv({
|
|
|
366
495
|
);
|
|
367
496
|
} else {
|
|
368
497
|
await fs5.outputFile(
|
|
369
|
-
|
|
498
|
+
path2.join(location, "env.ts"),
|
|
370
499
|
`${content}
|
|
371
500
|
// Joined env definition
|
|
372
501
|
export const env = createEnv({
|
|
@@ -386,7 +515,385 @@ export const env = createEnv({
|
|
|
386
515
|
var init_env = __esm({
|
|
387
516
|
"src/services/env.ts"() {
|
|
388
517
|
"use strict";
|
|
518
|
+
init_esm_shims();
|
|
519
|
+
init_pm();
|
|
520
|
+
init_options();
|
|
521
|
+
init_handle_cancel();
|
|
522
|
+
}
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
// src/services/test.ts
|
|
526
|
+
import { select as select5, log as log6 } from "@clack/prompts";
|
|
527
|
+
import fs6 from "fs-extra";
|
|
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 };
|
|
538
|
+
}
|
|
539
|
+
async function installTest(config2) {
|
|
540
|
+
const runner = config2.get("test").options.runner;
|
|
541
|
+
if (runner === "vitest") {
|
|
542
|
+
await installPackages(["vitest"], true);
|
|
543
|
+
const configFile = "vitest.config.ts";
|
|
544
|
+
if (!await fs6.pathExists(configFile)) {
|
|
545
|
+
await fs6.outputFile(
|
|
546
|
+
configFile,
|
|
547
|
+
`import { defineConfig } from 'vitest/config';
|
|
548
|
+
|
|
549
|
+
export default defineConfig({
|
|
550
|
+
test: {
|
|
551
|
+
environment: 'node',
|
|
552
|
+
},
|
|
553
|
+
});
|
|
554
|
+
`
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
} else if (runner === "jest") {
|
|
558
|
+
await installPackages(["jest", "ts-jest", "@types/jest"], true);
|
|
559
|
+
const configFile = "jest.config.js";
|
|
560
|
+
if (!await fs6.pathExists(configFile)) {
|
|
561
|
+
await fs6.outputFile(
|
|
562
|
+
configFile,
|
|
563
|
+
`/** @type {import('ts-jest').JestConfigWithTsJest} */
|
|
564
|
+
module.exports = {
|
|
565
|
+
preset: 'ts-jest',
|
|
566
|
+
testEnvironment: 'node',
|
|
567
|
+
};
|
|
568
|
+
`
|
|
569
|
+
);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
var init_test = __esm({
|
|
574
|
+
"src/services/test.ts"() {
|
|
575
|
+
"use strict";
|
|
576
|
+
init_esm_shims();
|
|
389
577
|
init_pm();
|
|
578
|
+
init_options();
|
|
579
|
+
init_handle_cancel();
|
|
580
|
+
}
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
// src/services/editor-config.ts
|
|
584
|
+
import { select as select6, log as log7 } from "@clack/prompts";
|
|
585
|
+
import fs7 from "fs-extra";
|
|
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 };
|
|
598
|
+
}
|
|
599
|
+
async function installEditorConfig(config2) {
|
|
600
|
+
let content = "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n";
|
|
601
|
+
const preset = config2.get("editorConfig").options.preset;
|
|
602
|
+
if (preset === "default") {
|
|
603
|
+
content += "indent_style = space\nindent_size = 2\n";
|
|
604
|
+
} else if (preset === "spaces4") {
|
|
605
|
+
content += "indent_style = space\nindent_size = 4\n";
|
|
606
|
+
} else if (preset === "tabs") {
|
|
607
|
+
content += "indent_style = tab\n";
|
|
608
|
+
}
|
|
609
|
+
await fs7.outputFile(".editorconfig", content);
|
|
610
|
+
}
|
|
611
|
+
var init_editor_config = __esm({
|
|
612
|
+
"src/services/editor-config.ts"() {
|
|
613
|
+
"use strict";
|
|
614
|
+
init_esm_shims();
|
|
615
|
+
init_options();
|
|
616
|
+
init_handle_cancel();
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
|
|
620
|
+
// src/services/license.ts
|
|
621
|
+
import { text as text3, select as select7, log as log8 } from "@clack/prompts";
|
|
622
|
+
import fs8 from "fs-extra";
|
|
623
|
+
import path3 from "path";
|
|
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
|
+
);
|
|
655
|
+
}
|
|
656
|
+
async function installLicense(config2) {
|
|
657
|
+
const licenseOptions = config2.get("license").options;
|
|
658
|
+
const { type, name, email, website } = licenseOptions;
|
|
659
|
+
if (type !== "UNLICENSED") {
|
|
660
|
+
const year = (/* @__PURE__ */ new Date()).getFullYear().toString();
|
|
661
|
+
const templatePath = path3.join(__dirname, "licenses", `${type}.txt`);
|
|
662
|
+
if (await fs8.pathExists(templatePath)) {
|
|
663
|
+
let licenseContent = await fs8.readFile(templatePath, "utf-8");
|
|
664
|
+
licenseContent = licenseContent.replace(/{YEAR}/g, year);
|
|
665
|
+
licenseContent = licenseContent.replace(/{HOLDER}/g, name || "");
|
|
666
|
+
licenseContent = licenseContent.replace(/{EMAIL}/g, email || "");
|
|
667
|
+
licenseContent = licenseContent.replace(/{WEBSITE}/g, website || "");
|
|
668
|
+
await fs8.outputFile("LICENSE", licenseContent);
|
|
669
|
+
} else {
|
|
670
|
+
const simpleContent = `Copyright (c) ${year} ${name}
|
|
671
|
+
Licensed under ${type}`;
|
|
672
|
+
await fs8.outputFile("LICENSE", simpleContent);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
if (await fs8.pathExists("package.json")) {
|
|
676
|
+
const pkg = await fs8.readJson("package.json");
|
|
677
|
+
pkg.license = type;
|
|
678
|
+
if (name) {
|
|
679
|
+
pkg.author = { name, email, url: website };
|
|
680
|
+
}
|
|
681
|
+
await fs8.writeJson("package.json", pkg, { spaces: 2 });
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
var init_license = __esm({
|
|
685
|
+
"src/services/license.ts"() {
|
|
686
|
+
"use strict";
|
|
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");
|
|
390
897
|
}
|
|
391
898
|
});
|
|
392
899
|
|
|
@@ -415,6 +922,41 @@ async function commitChanges(message) {
|
|
|
415
922
|
var init_git = __esm({
|
|
416
923
|
"src/utils/git.ts"() {
|
|
417
924
|
"use strict";
|
|
925
|
+
init_esm_shims();
|
|
926
|
+
}
|
|
927
|
+
});
|
|
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 = 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();
|
|
418
960
|
}
|
|
419
961
|
});
|
|
420
962
|
|
|
@@ -424,7 +966,7 @@ var init_package = __esm({
|
|
|
424
966
|
"package.json"() {
|
|
425
967
|
package_default = {
|
|
426
968
|
name: "@mayrlabs/setup-project",
|
|
427
|
-
version: "0.1.
|
|
969
|
+
version: "0.1.5",
|
|
428
970
|
description: "Interactive CLI to setup project tools",
|
|
429
971
|
private: false,
|
|
430
972
|
publishConfig: {
|
|
@@ -457,7 +999,11 @@ var init_package = __esm({
|
|
|
457
999
|
directory: "packages/setup-project"
|
|
458
1000
|
},
|
|
459
1001
|
license: "MIT",
|
|
460
|
-
author:
|
|
1002
|
+
author: {
|
|
1003
|
+
name: "Aghogho Meyoron",
|
|
1004
|
+
email: "youngmayor.dev@gmail.com",
|
|
1005
|
+
url: "https://mayrlabs.com"
|
|
1006
|
+
},
|
|
461
1007
|
type: "commonjs",
|
|
462
1008
|
main: "dist/index.js",
|
|
463
1009
|
scripts: {
|
|
@@ -469,143 +1015,188 @@ var init_package = __esm({
|
|
|
469
1015
|
"@clack/prompts": "^0.7.0",
|
|
470
1016
|
commander: "^11.1.0",
|
|
471
1017
|
execa: "^8.0.1",
|
|
1018
|
+
figlet: "^1.10.0",
|
|
472
1019
|
"fs-extra": "^11.2.0",
|
|
473
1020
|
picocolors: "^1.0.0",
|
|
474
1021
|
zod: "^3.22.4"
|
|
475
1022
|
},
|
|
476
1023
|
devDependencies: {
|
|
1024
|
+
"@types/figlet": "^1.7.0",
|
|
477
1025
|
"@types/fs-extra": "^11.0.4",
|
|
478
1026
|
"@types/node": "^20.11.16",
|
|
479
1027
|
tsup: "^8.5.1",
|
|
1028
|
+
tsx: "^4.21.0",
|
|
480
1029
|
typescript: "^5.3.3"
|
|
481
1030
|
}
|
|
482
1031
|
};
|
|
483
1032
|
}
|
|
484
1033
|
});
|
|
485
1034
|
|
|
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();
|
|
1053
|
+
}
|
|
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"() {
|
|
1092
|
+
"use strict";
|
|
1093
|
+
init_esm_shims();
|
|
1094
|
+
init_package();
|
|
1095
|
+
}
|
|
1096
|
+
});
|
|
1097
|
+
|
|
486
1098
|
// src/index.ts
|
|
487
|
-
import {
|
|
488
|
-
|
|
489
|
-
outro,
|
|
490
|
-
multiselect as multiselect3,
|
|
491
|
-
isCancel,
|
|
492
|
-
cancel,
|
|
493
|
-
note,
|
|
494
|
-
confirm as confirm2,
|
|
495
|
-
spinner
|
|
496
|
-
} from "@clack/prompts";
|
|
497
|
-
import pc from "picocolors";
|
|
1099
|
+
import { outro, multiselect as multiselect3, note, confirm as confirm4, intro } from "@clack/prompts";
|
|
1100
|
+
import pc11 from "picocolors";
|
|
498
1101
|
import { program } from "commander";
|
|
499
1102
|
var require_index = __commonJS({
|
|
500
1103
|
"src/index.ts"() {
|
|
1104
|
+
init_esm_shims();
|
|
501
1105
|
init_husky();
|
|
502
1106
|
init_formatter();
|
|
503
1107
|
init_linter();
|
|
504
1108
|
init_lint_staged();
|
|
505
1109
|
init_env();
|
|
506
|
-
|
|
507
|
-
|
|
1110
|
+
init_test();
|
|
1111
|
+
init_editor_config();
|
|
1112
|
+
init_license();
|
|
1113
|
+
init_config();
|
|
1114
|
+
init_handle_cancel();
|
|
1115
|
+
init_options();
|
|
1116
|
+
init_execution();
|
|
1117
|
+
init_logger();
|
|
1118
|
+
init_git_check();
|
|
1119
|
+
init_display();
|
|
508
1120
|
async function main() {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
1121
|
+
try {
|
|
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."));
|
|
1151
|
+
process.exit(0);
|
|
532
1152
|
}
|
|
1153
|
+
await execution(config);
|
|
1154
|
+
outro(pc11.green("Setup complete!"));
|
|
1155
|
+
} catch (error) {
|
|
1156
|
+
const logPath = await logError(error);
|
|
1157
|
+
outro(pc11.red(`
|
|
1158
|
+
Something went wrong!
|
|
1159
|
+
Error log saved to: ${logPath}`));
|
|
1160
|
+
process.exit(1);
|
|
533
1161
|
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
1162
|
+
}
|
|
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();
|
|
547
1184
|
process.exit(0);
|
|
548
1185
|
}
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
husky: selectedTools.includes("husky"),
|
|
552
|
-
formatter: selectedTools.includes("formatter"),
|
|
553
|
-
linter: selectedTools.includes("linter"),
|
|
554
|
-
lintStaged: selectedTools.includes("lint-staged"),
|
|
555
|
-
env: selectedTools.includes("env")
|
|
556
|
-
};
|
|
557
|
-
if (config.husky) await promptHusky(config);
|
|
558
|
-
if (config.formatter) await promptFormatter(config);
|
|
559
|
-
if (config.linter) await promptLinter(config);
|
|
560
|
-
if (config.lintStaged) await promptLintStaged(config);
|
|
561
|
-
if (config.env) await promptEnv(config);
|
|
562
|
-
let summary = "The following actions will be performed:\n\n";
|
|
563
|
-
if (config.husky) summary += "- Install and configure Husky\n";
|
|
564
|
-
if (config.formatter)
|
|
565
|
-
summary += `- Install and configure ${config.formatterChoice}
|
|
566
|
-
`;
|
|
567
|
-
if (config.linter)
|
|
568
|
-
summary += `- Install and configure ${config.linterChoice}
|
|
569
|
-
`;
|
|
570
|
-
if (config.lintStaged) summary += "- Install and configure Lint-staged\n";
|
|
571
|
-
if (config.env) summary += "- Install and configure @t3-oss/env\n";
|
|
572
|
-
note(summary, "Configuration Summary");
|
|
573
|
-
const proceed = await confirm2({
|
|
574
|
-
message: "Do you want to proceed with the installation?"
|
|
575
|
-
});
|
|
576
|
-
if (!proceed || isCancel(proceed)) {
|
|
577
|
-
cancel("Installation cancelled. Configuration saved.");
|
|
1186
|
+
if (options.version) {
|
|
1187
|
+
introScreen();
|
|
578
1188
|
process.exit(0);
|
|
579
1189
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
await installHusky(config);
|
|
584
|
-
s.stop("Husky setup complete.");
|
|
585
|
-
}
|
|
586
|
-
if (config.formatter) {
|
|
587
|
-
s.start(`Setting up ${config.formatterChoice}...`);
|
|
588
|
-
await installFormatter(config);
|
|
589
|
-
s.stop(`${config.formatterChoice} setup complete.`);
|
|
590
|
-
}
|
|
591
|
-
if (config.linter) {
|
|
592
|
-
s.start(`Setting up ${config.linterChoice}...`);
|
|
593
|
-
await installLinter(config);
|
|
594
|
-
s.stop(`${config.linterChoice} setup complete.`);
|
|
595
|
-
}
|
|
596
|
-
if (config.lintStaged) {
|
|
597
|
-
s.start("Setting up Lint-staged...");
|
|
598
|
-
await installLintStaged(config);
|
|
599
|
-
s.stop("Lint-staged setup complete.");
|
|
1190
|
+
if (options.visit) {
|
|
1191
|
+
showVisit();
|
|
1192
|
+
process.exit(0);
|
|
600
1193
|
}
|
|
601
|
-
if (
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
s.stop("Env Validation setup complete.");
|
|
1194
|
+
if (options.help) {
|
|
1195
|
+
showManual();
|
|
1196
|
+
process.exit(0);
|
|
605
1197
|
}
|
|
606
|
-
|
|
607
|
-
}
|
|
608
|
-
program.name("setup-project").description("Interactive setup for common project tools").version(package_default.version).action(main);
|
|
1198
|
+
await main();
|
|
1199
|
+
});
|
|
609
1200
|
program.parse();
|
|
610
1201
|
}
|
|
611
1202
|
});
|
|
@@ -616,4 +1207,3 @@ export default require_index();
|
|
|
616
1207
|
* Software should feel intentional.
|
|
617
1208
|
*/
|
|
618
1209
|
|
|
619
|
-
//# sourceMappingURL=index.mjs.map
|