create-better-fullstack 2.0.2 → 2.1.0

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.
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env node
2
+ import { cancel } from "@clack/prompts";
3
+ import pc from "picocolors";
4
+ import { AsyncLocalStorage } from "node:async_hooks";
5
+ import consola from "consola";
6
+
7
+ //#region src/utils/context.ts
8
+ const cliStorage = new AsyncLocalStorage();
9
+ function defaultContext() {
10
+ return {
11
+ navigation: {
12
+ isFirstPrompt: false,
13
+ lastPromptShownUI: false
14
+ },
15
+ silent: false
16
+ };
17
+ }
18
+ function getContext() {
19
+ const ctx = cliStorage.getStore();
20
+ if (!ctx) return defaultContext();
21
+ return ctx;
22
+ }
23
+ function tryGetContext() {
24
+ return cliStorage.getStore();
25
+ }
26
+ function isSilent() {
27
+ return getContext().silent;
28
+ }
29
+ function isFirstPrompt() {
30
+ return getContext().navigation.isFirstPrompt;
31
+ }
32
+ function didLastPromptShowUI() {
33
+ return getContext().navigation.lastPromptShownUI;
34
+ }
35
+ function setIsFirstPrompt(value) {
36
+ const ctx = tryGetContext();
37
+ if (ctx) ctx.navigation.isFirstPrompt = value;
38
+ }
39
+ function setLastPromptShownUI(value) {
40
+ const ctx = tryGetContext();
41
+ if (ctx) ctx.navigation.lastPromptShownUI = value;
42
+ }
43
+ async function runWithContextAsync(options, fn) {
44
+ const ctx = {
45
+ navigation: {
46
+ isFirstPrompt: false,
47
+ lastPromptShownUI: false
48
+ },
49
+ silent: options.silent ?? false
50
+ };
51
+ return cliStorage.run(ctx, fn);
52
+ }
53
+
54
+ //#endregion
55
+ //#region src/utils/errors.ts
56
+ var UserCancelledError = class extends Error {
57
+ constructor(message = "Operation cancelled") {
58
+ super(message);
59
+ this.name = "UserCancelledError";
60
+ }
61
+ };
62
+ var CLIError = class extends Error {
63
+ constructor(message) {
64
+ super(message);
65
+ this.name = "CLIError";
66
+ }
67
+ };
68
+ function exitWithError(message) {
69
+ if (isSilent()) throw new CLIError(message);
70
+ consola.error(pc.red(message));
71
+ process.exit(1);
72
+ }
73
+ function exitCancelled(message = "Operation cancelled") {
74
+ if (isSilent()) throw new UserCancelledError(message);
75
+ cancel(pc.red(message));
76
+ process.exit(1);
77
+ }
78
+ function handleError(error, fallbackMessage) {
79
+ const message = error instanceof Error ? error.message : fallbackMessage || String(error);
80
+ if (isSilent()) throw error instanceof Error ? error : new Error(message);
81
+ consola.error(pc.red(message));
82
+ process.exit(1);
83
+ }
84
+
85
+ //#endregion
86
+ export { handleError as a, isSilent as c, setLastPromptShownUI as d, exitWithError as i, runWithContextAsync as l, UserCancelledError as n, didLastPromptShowUI as o, exitCancelled as r, isFirstPrompt as s, CLIError as t, setIsFirstPrompt as u };
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env node
2
+ import { _ as getPrimaryGraphPart } from "./bts-config-InNcw1aJ.mjs";
3
+ import { log, spinner } from "@clack/prompts";
4
+ import pc from "picocolors";
5
+ import path from "node:path";
6
+ import { $ } from "execa";
7
+
8
+ //#region src/utils/command-exists.ts
9
+ async function commandExists(command) {
10
+ try {
11
+ if (process.platform === "win32") return (await $({ reject: false })`where ${command}`).exitCode === 0;
12
+ return (await $({ reject: false })`which ${command}`).exitCode === 0;
13
+ } catch {
14
+ return false;
15
+ }
16
+ }
17
+
18
+ //#endregion
19
+ //#region src/utils/generated-checks.ts
20
+ function getGraphTarget(config) {
21
+ const backend = getPrimaryGraphPart(config, "backend");
22
+ if (!backend || backend.ecosystem === "typescript" || backend.ecosystem === "react-native" || backend.ecosystem === "universal") return null;
23
+ return {
24
+ ecosystem: backend.ecosystem,
25
+ projectDir: path.join(config.projectDir, backend.targetPath ?? "apps/server")
26
+ };
27
+ }
28
+ function getSingleEcosystemTarget(config) {
29
+ if (config.ecosystem === "typescript" || config.ecosystem === "react-native" || config.ecosystem === "java") return null;
30
+ return {
31
+ ecosystem: config.ecosystem,
32
+ projectDir: config.projectDir
33
+ };
34
+ }
35
+ async function runCommand(cwd, command, args) {
36
+ await $({
37
+ cwd,
38
+ stdout: "inherit",
39
+ stderr: "inherit"
40
+ })`${command} ${args}`;
41
+ }
42
+ async function verifyTarget(target) {
43
+ const s = spinner();
44
+ const cwd = target.projectDir;
45
+ switch (target.ecosystem) {
46
+ case "go":
47
+ s.start("Verifying generated Go server...");
48
+ await runCommand(cwd, "go", ["mod", "tidy"]);
49
+ await runCommand(cwd, "go", ["test", "./..."]);
50
+ s.stop("Generated Go server checks passed");
51
+ return;
52
+ case "rust":
53
+ s.start("Verifying generated Rust server...");
54
+ await runCommand(cwd, "cargo", ["check"]);
55
+ s.stop("Generated Rust server checks passed");
56
+ return;
57
+ case "python":
58
+ s.start("Verifying generated Python server...");
59
+ await runCommand(cwd, "uv", ["sync"]);
60
+ await runCommand(cwd, "uv", [
61
+ "run",
62
+ "ruff",
63
+ "check",
64
+ "."
65
+ ]);
66
+ s.stop("Generated Python server checks passed");
67
+ return;
68
+ case "elixir":
69
+ if (!await commandExists("mix")) {
70
+ log.warn(pc.yellow("Skipping Elixir verification because mix is not on PATH"));
71
+ return;
72
+ }
73
+ s.start("Verifying generated Elixir server...");
74
+ await runCommand(cwd, "mix", ["deps.get"]);
75
+ await runCommand(cwd, "mix", ["compile"]);
76
+ s.stop("Generated Elixir server checks passed");
77
+ return;
78
+ default: log.warn(pc.yellow(`No generated checks are configured for ${target.ecosystem}`));
79
+ }
80
+ }
81
+ async function runGeneratedChecks(config) {
82
+ const target = getGraphTarget(config) ?? getSingleEcosystemTarget(config);
83
+ if (!target) {
84
+ log.warn(pc.yellow("No generated checks are configured for this stack"));
85
+ return;
86
+ }
87
+ await verifyTarget(target);
88
+ }
89
+
90
+ //#endregion
91
+ export { commandExists as n, runGeneratedChecks as t };