create-better-fullstack 2.1.6 → 2.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{add-handler-CuPmSJRM.mjs → add-handler-ztNjzoMN.mjs} +43 -5
- package/dist/addons-setup-DnLjAzTw.mjs +7 -0
- package/dist/{addons-setup-C_lxdJqU.mjs → addons-setup-LaAj43NP.mjs} +3 -24
- package/dist/analytics-DVltG11u.mjs +170 -0
- package/dist/{bts-config-BceXPcpI.mjs → bts-config-DQVWvPDs.mjs} +70 -66
- package/dist/cli.mjs +2 -2
- package/dist/{config-processing-B_1wTe3g.mjs → config-processing-D9-F2Us9.mjs} +1 -1
- package/dist/{doctor-DucDyWfl.mjs → doctor-a4ca3SMd.mjs} +2 -2
- package/dist/{file-formatter-XU6ti05V.mjs → file-formatter-gvmrpd-g.mjs} +13 -1
- package/dist/{gen-DWx3Xu_K.mjs → gen-CCClL7Ve.mjs} +1 -1
- package/dist/{generated-checks-Dt4Xqp1x.mjs → generated-checks-BV9jol5h.mjs} +1 -1
- package/dist/index.d.mts +27 -21
- package/dist/index.mjs +10 -8
- package/dist/{install-dependencies-DHoYa3P-.mjs → install-dependencies-RoUyaE8o.mjs} +7 -2
- package/dist/mcp-492OkjcS.mjs +11 -0
- package/dist/mcp-entry.mjs +56 -18
- package/dist/prompt-environment-BR0Kkw2W.mjs +26 -0
- package/dist/{registry-CxeEOPot.mjs → registry-DSf2CEaU.mjs} +27 -13
- package/dist/run-CD8f7PHh.mjs +15 -0
- package/dist/{run-D80ZtSO8.mjs → run-T6g1jkfy.mjs} +1810 -444
- package/dist/scaffold-manifest-DGRyepdb.mjs +4 -0
- package/dist/{scaffold-manifest-GV1fbhpD.mjs → scaffold-manifest-Dyi0voqE.mjs} +13 -1
- package/dist/{update-C9_x2yBF.mjs → update-DJ8CI5KW.mjs} +3 -3
- package/package.json +3 -3
- package/dist/addons-setup-DEPfsn6z.mjs +0 -6
- package/dist/mcp-D9O5zgAA.mjs +0 -8
- package/dist/run-3AkXloH1.mjs +0 -13
- /package/dist/{update-deps-DLZAuT3V.mjs → update-deps-aD-iQw4U.mjs} +0 -0
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { c as
|
|
2
|
+
import { _ as DEFAULT_UI_LIBRARY_BY_FRONTEND, b as types_exports, c as getGraphBackendDeployInstructions, d as getGraphSummary, g as DEFAULT_CONFIG, h as BUILDER_URL, i as readBtsConfigFromFile, l as getGraphBackendUrl, m as getLatestCLIVersion, o as writeBtsConfig, p as hasGraphPart, t as buildBtsConfigForPersistence, u as getGraphPart, v as getDefaultConfig, y as getUserPkgManager } from "./bts-config-DQVWvPDs.mjs";
|
|
3
3
|
import { t as renderTitle } from "./render-title-zvyKC1ej.mjs";
|
|
4
4
|
import { a as handleError, c as isSilent, d as setLastPromptShownUI, i as exitWithError, l as runWithContextAsync, n as UserCancelledError, o as didLastPromptShowUI, r as exitCancelled, s as isFirstPrompt, t as CLIError, u as setIsFirstPrompt } from "./errors-ns_o2OKg.mjs";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { _ as
|
|
8
|
-
import { n as
|
|
9
|
-
import {
|
|
10
|
-
import { r as
|
|
11
|
-
import {
|
|
5
|
+
import { t as canPromptInteractively } from "./prompt-environment-BR0Kkw2W.mjs";
|
|
6
|
+
import { a as trackProjectCreation, i as trackEvent, n as isTelemetryEnabled, o as getPersistedTelemetryPreference, r as maybeShowTelemetryNotice, s as setTelemetryPreference, t as hasTelemetryEnvOverride } from "./analytics-DVltG11u.mjs";
|
|
7
|
+
import { _ as CreateCommandInputSchema, a as allowedApisForFrontends$1, c as getCompatibleUILibraries$1, d as isExampleChatSdkAllowed$1, f as isFrontendAllowedWithBackend$1, h as splitFrontends$1, i as validateFullConfig, l as hasWebStyling$1, m as requiresChatSdkVercelAI, n as formatProject, p as isWebFrontend$1, r as validateConfigForProgrammaticUse, s as getCompatibleCSSFrameworks$1, u as isExampleAIAllowed$1, v as CreateCommandOptionsSchema } from "./file-formatter-gvmrpd-g.mjs";
|
|
8
|
+
import { _ as isGoBack, a as runMavenTests, c as applyDependencyVersionChannel, d as isCancel$1, f as navigableConfirm, g as GO_BACK_SYMBOL, h as setIsFirstPrompt$1, i as runGradleTests, l as getAddonsChoice, m as navigableSelect, n as runCargoBuild, o as runMixCompile, p as navigableMultiselect, r as runGoModTidy, s as runUvSync, t as installDependencies } from "./install-dependencies-RoUyaE8o.mjs";
|
|
9
|
+
import { n as commandExists, t as runGeneratedChecks } from "./generated-checks-BV9jol5h.mjs";
|
|
10
|
+
import { a as getTemplateConfig, i as validateArrayOptions, n as getProvidedFlags, o as getTemplateDescription, r as processFlags, s as generateReproducibleCommand, t as applyEffectBackendDefaults } from "./config-processing-D9-F2Us9.mjs";
|
|
11
|
+
import { a as recordScaffoldManifest } from "./scaffold-manifest-Dyi0voqE.mjs";
|
|
12
|
+
import { n as getPackageExecutionArgs, r as addPackageDependency, t as setupAddons } from "./addons-setup-LaAj43NP.mjs";
|
|
13
|
+
import { cancel, confirm, intro, isCancel, log, note, outro, select, spinner, text } from "@clack/prompts";
|
|
12
14
|
import { createRouterClient, os } from "@orpc/server";
|
|
13
15
|
import pc from "picocolors";
|
|
14
16
|
import { createCli } from "trpc-cli";
|
|
@@ -22,10 +24,10 @@ import { $, execa } from "execa";
|
|
|
22
24
|
import os$1 from "node:os";
|
|
23
25
|
|
|
24
26
|
//#region src/utils/project-history.ts
|
|
25
|
-
const paths
|
|
27
|
+
const paths = envPaths("better-fullstack", { suffix: "" });
|
|
26
28
|
const HISTORY_FILE = "history.json";
|
|
27
29
|
function getHistoryPath() {
|
|
28
|
-
return path.join(paths
|
|
30
|
+
return path.join(paths.data, HISTORY_FILE);
|
|
29
31
|
}
|
|
30
32
|
function generateId() {
|
|
31
33
|
return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
@@ -48,7 +50,7 @@ async function readHistory() {
|
|
|
48
50
|
}
|
|
49
51
|
}
|
|
50
52
|
async function writeHistory(history$1) {
|
|
51
|
-
await fs.ensureDir(paths
|
|
53
|
+
await fs.ensureDir(paths.data);
|
|
52
54
|
await fs.writeJson(getHistoryPath(), history$1, { spaces: 2 });
|
|
53
55
|
}
|
|
54
56
|
async function addToHistory(config, reproducibleCommand) {
|
|
@@ -155,141 +157,13 @@ async function historyHandler(input) {
|
|
|
155
157
|
}
|
|
156
158
|
}
|
|
157
159
|
|
|
158
|
-
//#endregion
|
|
159
|
-
//#region src/utils/telemetry-settings.ts
|
|
160
|
-
const paths = envPaths("better-fullstack", { suffix: "" });
|
|
161
|
-
const SETTINGS_FILE = "telemetry.json";
|
|
162
|
-
function getSettingsPath() {
|
|
163
|
-
return path.join(paths.data, SETTINGS_FILE);
|
|
164
|
-
}
|
|
165
|
-
function emptySettings() {
|
|
166
|
-
return {
|
|
167
|
-
version: 1,
|
|
168
|
-
noticeShown: false
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
async function readTelemetrySettings() {
|
|
172
|
-
const settingsPath = getSettingsPath();
|
|
173
|
-
if (!await fs.pathExists(settingsPath)) return emptySettings();
|
|
174
|
-
try {
|
|
175
|
-
const data = await fs.readJson(settingsPath);
|
|
176
|
-
if (!data || typeof data !== "object") return emptySettings();
|
|
177
|
-
return {
|
|
178
|
-
version: typeof data.version === "number" ? data.version : 1,
|
|
179
|
-
enabled: typeof data.enabled === "boolean" ? data.enabled : void 0,
|
|
180
|
-
noticeShown: data.noticeShown === true
|
|
181
|
-
};
|
|
182
|
-
} catch {
|
|
183
|
-
return emptySettings();
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
async function writeTelemetrySettings(settings) {
|
|
187
|
-
await fs.ensureDir(paths.data);
|
|
188
|
-
await fs.writeJson(getSettingsPath(), settings, { spaces: 2 });
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* The user's explicit persisted preference, or `undefined` when they never chose.
|
|
192
|
-
*/
|
|
193
|
-
async function getPersistedTelemetryPreference() {
|
|
194
|
-
return (await readTelemetrySettings()).enabled;
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Persist an explicit opt-in/opt-out. Choosing a preference also marks the
|
|
198
|
-
* first-run notice as shown so it never appears afterwards.
|
|
199
|
-
*/
|
|
200
|
-
async function setTelemetryPreference(enabled) {
|
|
201
|
-
const settings = await readTelemetrySettings();
|
|
202
|
-
settings.enabled = enabled;
|
|
203
|
-
settings.noticeShown = true;
|
|
204
|
-
await writeTelemetrySettings(settings);
|
|
205
|
-
}
|
|
206
|
-
async function hasTelemetryNoticeBeenShown() {
|
|
207
|
-
return (await readTelemetrySettings()).noticeShown;
|
|
208
|
-
}
|
|
209
|
-
async function markTelemetryNoticeShown() {
|
|
210
|
-
const settings = await readTelemetrySettings();
|
|
211
|
-
settings.noticeShown = true;
|
|
212
|
-
await writeTelemetrySettings(settings);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
//#endregion
|
|
216
|
-
//#region src/utils/analytics.ts
|
|
217
|
-
const CONVEX_INGEST_URL = "https://curious-elephant-653.convex.site/api/analytics/ingest";
|
|
218
|
-
/**
|
|
219
|
-
* Whether telemetry is explicitly overridden at runtime.
|
|
220
|
-
*
|
|
221
|
-
* Only `BTS_TELEMETRY_DISABLED` is a runtime override: `BTS_TELEMETRY` is inlined
|
|
222
|
-
* by the bundler at build time (see tsdown.config.ts) and therefore acts as a
|
|
223
|
-
* build-time default, not a runtime switch.
|
|
224
|
-
*/
|
|
225
|
-
function hasTelemetryEnvOverride() {
|
|
226
|
-
return process.env.BTS_TELEMETRY_DISABLED !== void 0;
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Resolve whether telemetry is enabled.
|
|
230
|
-
*
|
|
231
|
-
* Precedence: runtime env override (`BTS_TELEMETRY_DISABLED`) > persisted
|
|
232
|
-
* preference > default. The default honors the build-time `BTS_TELEMETRY` flag
|
|
233
|
-
* (inlined by the bundler, "0" by default) and falls back to enabled when the
|
|
234
|
-
* flag is unset (e.g. running from source).
|
|
235
|
-
*
|
|
236
|
-
* `BTS_TELEMETRY` is intentionally evaluated last: the bundler replaces it with
|
|
237
|
-
* a literal, so an early `!== undefined` check would always short-circuit and
|
|
238
|
-
* make the persisted preference unreachable in the shipped CLI.
|
|
239
|
-
*/
|
|
240
|
-
async function isTelemetryEnabled() {
|
|
241
|
-
const disabled = process.env.BTS_TELEMETRY_DISABLED;
|
|
242
|
-
if (disabled !== void 0) return disabled !== "1";
|
|
243
|
-
const persisted = await getPersistedTelemetryPreference();
|
|
244
|
-
if (persisted !== void 0) return persisted;
|
|
245
|
-
const buildDefault = "1";
|
|
246
|
-
return buildDefault === void 0 ? true : buildDefault === "1";
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* Print a one-time notice describing the anonymous telemetry the CLI collects
|
|
250
|
-
* and how to opt out, then remember that it was shown so it never repeats.
|
|
251
|
-
*
|
|
252
|
-
* No-ops when telemetry is explicitly configured via env var, when a persisted
|
|
253
|
-
* preference already exists, when the notice was already shown, when telemetry
|
|
254
|
-
* is disabled by the build default, or when the CLI is not running interactively
|
|
255
|
-
* (CI / silent / non-TTY).
|
|
256
|
-
*/
|
|
257
|
-
async function maybeShowTelemetryNotice() {
|
|
258
|
-
if (hasTelemetryEnvOverride()) return;
|
|
259
|
-
if (!canPromptInteractively()) return;
|
|
260
|
-
if (await getPersistedTelemetryPreference() !== void 0) return;
|
|
261
|
-
if (await hasTelemetryNoticeBeenShown()) return;
|
|
262
|
-
if (!await isTelemetryEnabled()) return;
|
|
263
|
-
log.info(`${pc.bold("Anonymous usage telemetry is enabled.")}\n${pc.dim("We collect your selected stack options (e.g. frontend, backend, database),")}\n${pc.dim("plus CLI version, Node.js version, and OS platform — never project names,")}\n${pc.dim("file paths, or any personal data.")}\nOpt out anytime with ${pc.cyan("create-better-fullstack telemetry disable")} or ${pc.cyan("BTS_TELEMETRY_DISABLED=1")}.`);
|
|
264
|
-
try {
|
|
265
|
-
await markTelemetryNoticeShown();
|
|
266
|
-
} catch {}
|
|
267
|
-
}
|
|
268
|
-
async function sendConvexEvent(payload) {
|
|
269
|
-
try {
|
|
270
|
-
await fetch(CONVEX_INGEST_URL, {
|
|
271
|
-
method: "POST",
|
|
272
|
-
headers: { "Content-Type": "application/json" },
|
|
273
|
-
body: JSON.stringify(payload)
|
|
274
|
-
});
|
|
275
|
-
} catch {}
|
|
276
|
-
}
|
|
277
|
-
async function trackProjectCreation(config, disableAnalytics = false) {
|
|
278
|
-
if (disableAnalytics || !await isTelemetryEnabled()) return;
|
|
279
|
-
const { projectName: _projectName, projectDir: _projectDir, relativePath: _relativePath, ...safeConfig } = config;
|
|
280
|
-
try {
|
|
281
|
-
await sendConvexEvent({
|
|
282
|
-
...safeConfig,
|
|
283
|
-
cli_version: getLatestCLIVersion(),
|
|
284
|
-
node_version: typeof process !== "undefined" ? process.version : "",
|
|
285
|
-
platform: typeof process !== "undefined" ? process.platform : ""
|
|
286
|
-
});
|
|
287
|
-
} catch {}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
160
|
//#endregion
|
|
291
161
|
//#region src/commands/telemetry.ts
|
|
292
|
-
const COLLECTED = [
|
|
162
|
+
const COLLECTED = [
|
|
163
|
+
"Selected stack options (frontend, backend, database, ORM, auth, API, etc.)",
|
|
164
|
+
"CLI version, Node.js version, and OS platform",
|
|
165
|
+
"A random anonymous install ID used to count unique and returning installs"
|
|
166
|
+
];
|
|
293
167
|
const NOT_COLLECTED = ["Project names, directory paths, or file contents", "Personal or otherwise identifying information"];
|
|
294
168
|
function resolveSource(persisted) {
|
|
295
169
|
if (hasTelemetryEnvOverride()) return "env";
|
|
@@ -1020,6 +894,475 @@ async function getCMSChoice(cms, backend) {
|
|
|
1020
894
|
return response;
|
|
1021
895
|
}
|
|
1022
896
|
|
|
897
|
+
//#endregion
|
|
898
|
+
//#region src/prompts/config-scope.ts
|
|
899
|
+
const CONFIG_SCOPE_ALWAYS_KEYS = [
|
|
900
|
+
"aiDocs",
|
|
901
|
+
"git",
|
|
902
|
+
"workspaceShape",
|
|
903
|
+
"packageManager",
|
|
904
|
+
"install"
|
|
905
|
+
];
|
|
906
|
+
const sharedServiceSection = {
|
|
907
|
+
id: "shared-services",
|
|
908
|
+
label: "Shared Services",
|
|
909
|
+
promptKeys: [
|
|
910
|
+
"email",
|
|
911
|
+
"caching",
|
|
912
|
+
"search",
|
|
913
|
+
"observability"
|
|
914
|
+
]
|
|
915
|
+
};
|
|
916
|
+
const typescriptSections = [
|
|
917
|
+
{
|
|
918
|
+
id: "ui-styling",
|
|
919
|
+
label: "UI & Styling",
|
|
920
|
+
promptKeys: [
|
|
921
|
+
"uiLibrary",
|
|
922
|
+
"shadcnOptions",
|
|
923
|
+
"cssFramework"
|
|
924
|
+
]
|
|
925
|
+
},
|
|
926
|
+
{
|
|
927
|
+
id: "state-forms",
|
|
928
|
+
label: "State, Forms & Animation",
|
|
929
|
+
promptKeys: [
|
|
930
|
+
"stateManagement",
|
|
931
|
+
"forms",
|
|
932
|
+
"animation"
|
|
933
|
+
]
|
|
934
|
+
},
|
|
935
|
+
{
|
|
936
|
+
id: "type-safety",
|
|
937
|
+
label: "Validation & Effect",
|
|
938
|
+
promptKeys: ["validation", "effect"]
|
|
939
|
+
},
|
|
940
|
+
{
|
|
941
|
+
id: "payments-email",
|
|
942
|
+
label: "Payments & Email",
|
|
943
|
+
promptKeys: ["payments", "email"]
|
|
944
|
+
},
|
|
945
|
+
{
|
|
946
|
+
id: "ai",
|
|
947
|
+
label: "AI & Vector DB",
|
|
948
|
+
promptKeys: ["ai", "vectorDb"]
|
|
949
|
+
},
|
|
950
|
+
{
|
|
951
|
+
id: "data-storage",
|
|
952
|
+
label: "Data & Storage",
|
|
953
|
+
promptKeys: [
|
|
954
|
+
"caching",
|
|
955
|
+
"search",
|
|
956
|
+
"fileStorage",
|
|
957
|
+
"fileUpload"
|
|
958
|
+
]
|
|
959
|
+
},
|
|
960
|
+
{
|
|
961
|
+
id: "backend-extras",
|
|
962
|
+
label: "Jobs, Realtime & Rate Limiting",
|
|
963
|
+
promptKeys: [
|
|
964
|
+
"jobQueue",
|
|
965
|
+
"realtime",
|
|
966
|
+
"rateLimit"
|
|
967
|
+
]
|
|
968
|
+
},
|
|
969
|
+
{
|
|
970
|
+
id: "quality",
|
|
971
|
+
label: "Testing & Observability",
|
|
972
|
+
promptKeys: [
|
|
973
|
+
"testing",
|
|
974
|
+
"logging",
|
|
975
|
+
"observability"
|
|
976
|
+
]
|
|
977
|
+
},
|
|
978
|
+
{
|
|
979
|
+
id: "content",
|
|
980
|
+
label: "Content, Analytics & i18n",
|
|
981
|
+
promptKeys: [
|
|
982
|
+
"cms",
|
|
983
|
+
"analytics",
|
|
984
|
+
"i18n",
|
|
985
|
+
"featureFlags"
|
|
986
|
+
]
|
|
987
|
+
},
|
|
988
|
+
{
|
|
989
|
+
id: "deploy",
|
|
990
|
+
label: "Deployment",
|
|
991
|
+
promptKeys: ["webDeploy", "serverDeploy"]
|
|
992
|
+
},
|
|
993
|
+
{
|
|
994
|
+
id: "addons-examples",
|
|
995
|
+
label: "Addons & Examples",
|
|
996
|
+
promptKeys: ["addons", "examples"]
|
|
997
|
+
}
|
|
998
|
+
];
|
|
999
|
+
const CONFIG_SCOPE_REGISTRY = {
|
|
1000
|
+
typescript: {
|
|
1001
|
+
core: [
|
|
1002
|
+
"frontend",
|
|
1003
|
+
"astroIntegration",
|
|
1004
|
+
"backend",
|
|
1005
|
+
"runtime",
|
|
1006
|
+
"database",
|
|
1007
|
+
"orm",
|
|
1008
|
+
"api",
|
|
1009
|
+
"auth",
|
|
1010
|
+
"dbSetup"
|
|
1011
|
+
],
|
|
1012
|
+
sections: typescriptSections
|
|
1013
|
+
},
|
|
1014
|
+
"react-native": {
|
|
1015
|
+
core: [
|
|
1016
|
+
"frontend",
|
|
1017
|
+
"mobileNavigation",
|
|
1018
|
+
"backend",
|
|
1019
|
+
"runtime",
|
|
1020
|
+
"database",
|
|
1021
|
+
"orm",
|
|
1022
|
+
"api",
|
|
1023
|
+
"auth",
|
|
1024
|
+
"dbSetup"
|
|
1025
|
+
],
|
|
1026
|
+
sections: [
|
|
1027
|
+
{
|
|
1028
|
+
id: "mobile-experience",
|
|
1029
|
+
label: "Mobile Experience",
|
|
1030
|
+
promptKeys: [
|
|
1031
|
+
"mobileUI",
|
|
1032
|
+
"mobileStorage",
|
|
1033
|
+
"mobileDeepLinking"
|
|
1034
|
+
]
|
|
1035
|
+
},
|
|
1036
|
+
{
|
|
1037
|
+
id: "mobile-delivery",
|
|
1038
|
+
label: "Mobile Delivery",
|
|
1039
|
+
promptKeys: [
|
|
1040
|
+
"mobilePush",
|
|
1041
|
+
"mobileOTA",
|
|
1042
|
+
"mobileTesting"
|
|
1043
|
+
]
|
|
1044
|
+
},
|
|
1045
|
+
{
|
|
1046
|
+
id: "commerce",
|
|
1047
|
+
label: "Payments",
|
|
1048
|
+
promptKeys: ["payments"]
|
|
1049
|
+
},
|
|
1050
|
+
{
|
|
1051
|
+
id: "extras",
|
|
1052
|
+
label: "Data & Discovery",
|
|
1053
|
+
promptKeys: [
|
|
1054
|
+
"caching",
|
|
1055
|
+
"search",
|
|
1056
|
+
"observability"
|
|
1057
|
+
]
|
|
1058
|
+
}
|
|
1059
|
+
]
|
|
1060
|
+
},
|
|
1061
|
+
rust: {
|
|
1062
|
+
core: [
|
|
1063
|
+
"rustWebFramework",
|
|
1064
|
+
"rustFrontend",
|
|
1065
|
+
"database",
|
|
1066
|
+
"dbSetup",
|
|
1067
|
+
"rustOrm",
|
|
1068
|
+
"rustApi",
|
|
1069
|
+
"rustAuth"
|
|
1070
|
+
],
|
|
1071
|
+
sections: [
|
|
1072
|
+
sharedServiceSection,
|
|
1073
|
+
{
|
|
1074
|
+
id: "cli-libraries",
|
|
1075
|
+
label: "CLI & Libraries",
|
|
1076
|
+
promptKeys: [
|
|
1077
|
+
"rustCli",
|
|
1078
|
+
"rustLibraries",
|
|
1079
|
+
"rustTemplating"
|
|
1080
|
+
]
|
|
1081
|
+
},
|
|
1082
|
+
{
|
|
1083
|
+
id: "quality",
|
|
1084
|
+
label: "Logging & Error Handling",
|
|
1085
|
+
promptKeys: ["rustLogging", "rustErrorHandling"]
|
|
1086
|
+
},
|
|
1087
|
+
{
|
|
1088
|
+
id: "backend-extras",
|
|
1089
|
+
label: "Caching, Realtime & Queues",
|
|
1090
|
+
promptKeys: [
|
|
1091
|
+
"rustCaching",
|
|
1092
|
+
"rustRealtime",
|
|
1093
|
+
"rustMessageQueue"
|
|
1094
|
+
]
|
|
1095
|
+
},
|
|
1096
|
+
{
|
|
1097
|
+
id: "observability",
|
|
1098
|
+
label: "Observability",
|
|
1099
|
+
promptKeys: ["rustObservability"]
|
|
1100
|
+
}
|
|
1101
|
+
]
|
|
1102
|
+
},
|
|
1103
|
+
python: {
|
|
1104
|
+
core: [
|
|
1105
|
+
"pythonWebFramework",
|
|
1106
|
+
"database",
|
|
1107
|
+
"dbSetup",
|
|
1108
|
+
"pythonOrm",
|
|
1109
|
+
"pythonAuth",
|
|
1110
|
+
"pythonApi"
|
|
1111
|
+
],
|
|
1112
|
+
sections: [
|
|
1113
|
+
sharedServiceSection,
|
|
1114
|
+
{
|
|
1115
|
+
id: "type-safety-ai",
|
|
1116
|
+
label: "Validation & AI",
|
|
1117
|
+
promptKeys: ["pythonValidation", "pythonAi"]
|
|
1118
|
+
},
|
|
1119
|
+
{
|
|
1120
|
+
id: "api-jobs",
|
|
1121
|
+
label: "GraphQL, Tasks & CLI",
|
|
1122
|
+
promptKeys: [
|
|
1123
|
+
"pythonGraphql",
|
|
1124
|
+
"pythonTaskQueue",
|
|
1125
|
+
"pythonCli"
|
|
1126
|
+
]
|
|
1127
|
+
},
|
|
1128
|
+
{
|
|
1129
|
+
id: "data-realtime",
|
|
1130
|
+
label: "Caching & Realtime",
|
|
1131
|
+
promptKeys: ["pythonCaching", "pythonRealtime"]
|
|
1132
|
+
},
|
|
1133
|
+
{
|
|
1134
|
+
id: "quality",
|
|
1135
|
+
label: "Quality, Testing & Observability",
|
|
1136
|
+
promptKeys: [
|
|
1137
|
+
"pythonQuality",
|
|
1138
|
+
"pythonTesting",
|
|
1139
|
+
"pythonObservability"
|
|
1140
|
+
]
|
|
1141
|
+
}
|
|
1142
|
+
]
|
|
1143
|
+
},
|
|
1144
|
+
go: {
|
|
1145
|
+
core: [
|
|
1146
|
+
"goWebFramework",
|
|
1147
|
+
"database",
|
|
1148
|
+
"dbSetup",
|
|
1149
|
+
"goOrm",
|
|
1150
|
+
"goApi",
|
|
1151
|
+
"goAuth"
|
|
1152
|
+
],
|
|
1153
|
+
sections: [
|
|
1154
|
+
sharedServiceSection,
|
|
1155
|
+
{
|
|
1156
|
+
id: "cli-config",
|
|
1157
|
+
label: "CLI, Config & Logging",
|
|
1158
|
+
promptKeys: [
|
|
1159
|
+
"goCli",
|
|
1160
|
+
"goConfig",
|
|
1161
|
+
"goLogging"
|
|
1162
|
+
]
|
|
1163
|
+
},
|
|
1164
|
+
{
|
|
1165
|
+
id: "backend-extras",
|
|
1166
|
+
label: "Realtime, Queues & Caching",
|
|
1167
|
+
promptKeys: [
|
|
1168
|
+
"goRealtime",
|
|
1169
|
+
"goMessageQueue",
|
|
1170
|
+
"goCaching"
|
|
1171
|
+
]
|
|
1172
|
+
},
|
|
1173
|
+
{
|
|
1174
|
+
id: "quality",
|
|
1175
|
+
label: "Testing & Observability",
|
|
1176
|
+
promptKeys: ["goTesting", "goObservability"]
|
|
1177
|
+
}
|
|
1178
|
+
]
|
|
1179
|
+
},
|
|
1180
|
+
java: {
|
|
1181
|
+
core: [
|
|
1182
|
+
"javaWebFramework",
|
|
1183
|
+
"javaLanguage",
|
|
1184
|
+
"javaBuildTool",
|
|
1185
|
+
"database",
|
|
1186
|
+
"dbSetup",
|
|
1187
|
+
"javaOrm",
|
|
1188
|
+
"javaAuth",
|
|
1189
|
+
"javaApi"
|
|
1190
|
+
],
|
|
1191
|
+
sections: [
|
|
1192
|
+
sharedServiceSection,
|
|
1193
|
+
{
|
|
1194
|
+
id: "libraries",
|
|
1195
|
+
label: "Libraries",
|
|
1196
|
+
promptKeys: ["javaLibraries"]
|
|
1197
|
+
},
|
|
1198
|
+
{
|
|
1199
|
+
id: "quality",
|
|
1200
|
+
label: "Logging & Testing",
|
|
1201
|
+
promptKeys: ["javaLogging", "javaTestingLibraries"]
|
|
1202
|
+
}
|
|
1203
|
+
]
|
|
1204
|
+
},
|
|
1205
|
+
dotnet: {
|
|
1206
|
+
core: [
|
|
1207
|
+
"dotnetWebFramework",
|
|
1208
|
+
"database",
|
|
1209
|
+
"dbSetup",
|
|
1210
|
+
"dotnetOrm",
|
|
1211
|
+
"dotnetAuth",
|
|
1212
|
+
"dotnetApi"
|
|
1213
|
+
],
|
|
1214
|
+
sections: [
|
|
1215
|
+
sharedServiceSection,
|
|
1216
|
+
{
|
|
1217
|
+
id: "quality",
|
|
1218
|
+
label: "Testing & Observability",
|
|
1219
|
+
promptKeys: ["dotnetTesting", "dotnetObservability"]
|
|
1220
|
+
},
|
|
1221
|
+
{
|
|
1222
|
+
id: "backend-extras",
|
|
1223
|
+
label: "Jobs, Realtime & Caching",
|
|
1224
|
+
promptKeys: [
|
|
1225
|
+
"dotnetJobQueue",
|
|
1226
|
+
"dotnetRealtime",
|
|
1227
|
+
"dotnetCaching"
|
|
1228
|
+
]
|
|
1229
|
+
},
|
|
1230
|
+
{
|
|
1231
|
+
id: "validation-deploy",
|
|
1232
|
+
label: "Validation & Deployment",
|
|
1233
|
+
promptKeys: ["dotnetValidation", "dotnetDeploy"]
|
|
1234
|
+
}
|
|
1235
|
+
]
|
|
1236
|
+
},
|
|
1237
|
+
elixir: {
|
|
1238
|
+
core: [
|
|
1239
|
+
"elixirWebFramework",
|
|
1240
|
+
"database",
|
|
1241
|
+
"dbSetup",
|
|
1242
|
+
"elixirOrm",
|
|
1243
|
+
"elixirAuth",
|
|
1244
|
+
"elixirApi"
|
|
1245
|
+
],
|
|
1246
|
+
sections: [
|
|
1247
|
+
{
|
|
1248
|
+
id: "backend-extras",
|
|
1249
|
+
label: "Realtime & Jobs",
|
|
1250
|
+
promptKeys: ["elixirRealtime", "elixirJobs"]
|
|
1251
|
+
},
|
|
1252
|
+
{
|
|
1253
|
+
id: "type-safety-http",
|
|
1254
|
+
label: "Validation, HTTP & JSON",
|
|
1255
|
+
promptKeys: [
|
|
1256
|
+
"elixirValidation",
|
|
1257
|
+
"elixirHttp",
|
|
1258
|
+
"elixirJson"
|
|
1259
|
+
]
|
|
1260
|
+
},
|
|
1261
|
+
{
|
|
1262
|
+
id: "data-email",
|
|
1263
|
+
label: "Email & Caching",
|
|
1264
|
+
promptKeys: ["elixirEmail", "elixirCaching"]
|
|
1265
|
+
},
|
|
1266
|
+
{
|
|
1267
|
+
id: "quality",
|
|
1268
|
+
label: "Testing, Quality & Observability",
|
|
1269
|
+
promptKeys: [
|
|
1270
|
+
"elixirTesting",
|
|
1271
|
+
"elixirQuality",
|
|
1272
|
+
"elixirObservability"
|
|
1273
|
+
]
|
|
1274
|
+
},
|
|
1275
|
+
{
|
|
1276
|
+
id: "deploy-libraries",
|
|
1277
|
+
label: "Deployment & Libraries",
|
|
1278
|
+
promptKeys: ["elixirDeploy", "elixirLibraries"]
|
|
1279
|
+
}
|
|
1280
|
+
]
|
|
1281
|
+
}
|
|
1282
|
+
};
|
|
1283
|
+
const SCOPED_CONFIG_PROMPT_KEYS = [...new Set(Object.values(CONFIG_SCOPE_REGISTRY).flatMap((registry) => [
|
|
1284
|
+
...registry.core,
|
|
1285
|
+
...registry.sections.flatMap((section) => section.promptKeys),
|
|
1286
|
+
...CONFIG_SCOPE_ALWAYS_KEYS
|
|
1287
|
+
]))].sort();
|
|
1288
|
+
function getConfigScopePromptKeys(ecosystem, scope, selectedSectionIds = []) {
|
|
1289
|
+
const registry = CONFIG_SCOPE_REGISTRY[ecosystem];
|
|
1290
|
+
const keys = new Set([...registry.core, ...CONFIG_SCOPE_ALWAYS_KEYS]);
|
|
1291
|
+
if (scope === "full") for (const section of registry.sections) for (const key of section.promptKeys) keys.add(key);
|
|
1292
|
+
if (scope === "custom") {
|
|
1293
|
+
const selected = new Set(selectedSectionIds);
|
|
1294
|
+
for (const section of registry.sections) {
|
|
1295
|
+
if (!selected.has(section.id)) continue;
|
|
1296
|
+
for (const key of section.promptKeys) keys.add(key);
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
return keys;
|
|
1300
|
+
}
|
|
1301
|
+
function shouldAskConfigPromptKey(ecosystem, key, scope, selectedSectionIds) {
|
|
1302
|
+
if (!ecosystem || !scope || scope === "full") return true;
|
|
1303
|
+
const registry = CONFIG_SCOPE_REGISTRY[ecosystem];
|
|
1304
|
+
if (!new Set([
|
|
1305
|
+
...registry.core,
|
|
1306
|
+
...registry.sections.flatMap((section) => section.promptKeys),
|
|
1307
|
+
...CONFIG_SCOPE_ALWAYS_KEYS
|
|
1308
|
+
]).has(key)) return true;
|
|
1309
|
+
return getConfigScopePromptKeys(ecosystem, scope, selectedSectionIds).has(key);
|
|
1310
|
+
}
|
|
1311
|
+
function getDefaultPromptValue(key) {
|
|
1312
|
+
if (key === "astroIntegration") return void 0;
|
|
1313
|
+
const defaults = getDefaultConfig();
|
|
1314
|
+
if (key === "shadcnOptions") return {
|
|
1315
|
+
shadcnBase: defaults.shadcnBase,
|
|
1316
|
+
shadcnStyle: defaults.shadcnStyle,
|
|
1317
|
+
shadcnIconLibrary: defaults.shadcnIconLibrary,
|
|
1318
|
+
shadcnColorTheme: defaults.shadcnColorTheme,
|
|
1319
|
+
shadcnBaseColor: defaults.shadcnBaseColor,
|
|
1320
|
+
shadcnFont: defaults.shadcnFont,
|
|
1321
|
+
shadcnRadius: defaults.shadcnRadius
|
|
1322
|
+
};
|
|
1323
|
+
return defaults[key];
|
|
1324
|
+
}
|
|
1325
|
+
async function getConfigScopeChoice() {
|
|
1326
|
+
const response = await navigableSelect({
|
|
1327
|
+
message: "How much do you want to configure?",
|
|
1328
|
+
options: [
|
|
1329
|
+
{
|
|
1330
|
+
value: "core",
|
|
1331
|
+
label: "Core",
|
|
1332
|
+
hint: "essentials only — framework, database, auth, API; sensible defaults for everything else"
|
|
1333
|
+
},
|
|
1334
|
+
{
|
|
1335
|
+
value: "full",
|
|
1336
|
+
label: "Full",
|
|
1337
|
+
hint: "walk through every option"
|
|
1338
|
+
},
|
|
1339
|
+
{
|
|
1340
|
+
value: "custom",
|
|
1341
|
+
label: "Custom",
|
|
1342
|
+
hint: "pick which sections to configure"
|
|
1343
|
+
}
|
|
1344
|
+
],
|
|
1345
|
+
initialValue: "core"
|
|
1346
|
+
});
|
|
1347
|
+
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
1348
|
+
return response;
|
|
1349
|
+
}
|
|
1350
|
+
async function getConfigSectionsChoice(ecosystem, initialValues = [], availableSectionIds) {
|
|
1351
|
+
const sections = CONFIG_SCOPE_REGISTRY[ecosystem].sections.filter((section) => !availableSectionIds || availableSectionIds.includes(section.id));
|
|
1352
|
+
const response = await navigableMultiselect({
|
|
1353
|
+
message: `Which sections do you want to configure? ${pc.dim("(essentials are always included)")}`,
|
|
1354
|
+
options: sections.map((section) => ({
|
|
1355
|
+
value: section.id,
|
|
1356
|
+
label: section.label
|
|
1357
|
+
})),
|
|
1358
|
+
initialValues,
|
|
1359
|
+
required: false
|
|
1360
|
+
});
|
|
1361
|
+
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
1362
|
+
if (isGoBack(response)) return response;
|
|
1363
|
+
return response;
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1023
1366
|
//#endregion
|
|
1024
1367
|
//#region src/prompts/css-framework.ts
|
|
1025
1368
|
const CSS_FRAMEWORK_OPTIONS = {
|
|
@@ -1565,6 +1908,16 @@ const DEPLOY_OPTIONS$1 = [
|
|
|
1565
1908
|
hint: "No .NET deploy target"
|
|
1566
1909
|
}
|
|
1567
1910
|
];
|
|
1911
|
+
const resolveDotnetWebFrameworkPrompt = (value) => createStaticSinglePromptResolution(WEB_FRAMEWORK_OPTIONS$1, "aspnet-minimal", value);
|
|
1912
|
+
const resolveDotnetOrmPrompt = (value) => createStaticSinglePromptResolution(ORM_OPTIONS$1, "ef-core", value);
|
|
1913
|
+
const resolveDotnetAuthPrompt = (value) => createStaticSinglePromptResolution(AUTH_OPTIONS$1, "aspnet-identity", value);
|
|
1914
|
+
const resolveDotnetApiPrompt = (value) => createStaticSinglePromptResolution(API_OPTIONS$1, "minimal-api", value);
|
|
1915
|
+
const resolveDotnetTestingPrompt = (value) => createStaticMultiPromptResolution(TESTING_OPTIONS$1, ["xunit"], value);
|
|
1916
|
+
const resolveDotnetJobQueuePrompt = (value) => createStaticSinglePromptResolution(JOB_QUEUE_OPTIONS, "none", value);
|
|
1917
|
+
const resolveDotnetRealtimePrompt = (value) => createStaticSinglePromptResolution(REALTIME_OPTIONS$1, "signalr", value);
|
|
1918
|
+
const resolveDotnetObservabilityPrompt = (value) => createStaticMultiPromptResolution(OBSERVABILITY_OPTIONS$1, ["serilog"], value);
|
|
1919
|
+
const resolveDotnetCachingPrompt = (value) => createStaticSinglePromptResolution(CACHING_OPTIONS$1, "none", value);
|
|
1920
|
+
const resolveDotnetDeployPrompt = (value) => createStaticSinglePromptResolution(DEPLOY_OPTIONS$1, "docker", value);
|
|
1568
1921
|
const getDotnetWebFrameworkChoice = (value) => makeChoice$1("Select .NET web framework", WEB_FRAMEWORK_OPTIONS$1, "aspnet-minimal", value);
|
|
1569
1922
|
const getDotnetOrmChoice = (value) => makeChoice$1("Select .NET data access", ORM_OPTIONS$1, "ef-core", value);
|
|
1570
1923
|
const getDotnetAuthChoice = (value) => makeChoice$1("Select .NET auth", AUTH_OPTIONS$1, "aspnet-identity", value);
|
|
@@ -1907,6 +2260,21 @@ const DEPLOY_OPTIONS = [
|
|
|
1907
2260
|
hint: "No deploy files"
|
|
1908
2261
|
}
|
|
1909
2262
|
];
|
|
2263
|
+
const resolveElixirWebFrameworkPrompt = (value) => createStaticSinglePromptResolution(WEB_FRAMEWORK_OPTIONS, "phoenix", value);
|
|
2264
|
+
const resolveElixirOrmPrompt = (value) => createStaticSinglePromptResolution(ORM_OPTIONS, "ecto-sql", value);
|
|
2265
|
+
const resolveElixirAuthPrompt = (value) => createStaticSinglePromptResolution(AUTH_OPTIONS, "none", value);
|
|
2266
|
+
const resolveElixirApiPrompt = (value) => createStaticSinglePromptResolution(API_OPTIONS, "rest", value);
|
|
2267
|
+
const resolveElixirRealtimePrompt = (value) => createStaticSinglePromptResolution(REALTIME_OPTIONS, "channels", value);
|
|
2268
|
+
const resolveElixirJobsPrompt = (value) => createStaticSinglePromptResolution(JOB_OPTIONS, "none", value);
|
|
2269
|
+
const resolveElixirValidationPrompt = (value) => createStaticSinglePromptResolution(VALIDATION_OPTIONS, "ecto-changesets", value);
|
|
2270
|
+
const resolveElixirHttpPrompt = (value) => createStaticSinglePromptResolution(HTTP_OPTIONS, "req", value);
|
|
2271
|
+
const resolveElixirJsonPrompt = (value) => createStaticSinglePromptResolution(JSON_OPTIONS, "jason", value);
|
|
2272
|
+
const resolveElixirEmailPrompt = (value) => createStaticSinglePromptResolution(EMAIL_OPTIONS, "none", value);
|
|
2273
|
+
const resolveElixirCachingPrompt = (value) => createStaticSinglePromptResolution(CACHING_OPTIONS, "none", value);
|
|
2274
|
+
const resolveElixirObservabilityPrompt = (value) => createStaticSinglePromptResolution(OBSERVABILITY_OPTIONS, "telemetry", value);
|
|
2275
|
+
const resolveElixirTestingPrompt = (value) => createStaticSinglePromptResolution(TESTING_OPTIONS, "ex_unit", value);
|
|
2276
|
+
const resolveElixirQualityPrompt = (value) => createStaticSinglePromptResolution(QUALITY_OPTIONS, "credo", value);
|
|
2277
|
+
const resolveElixirDeployPrompt = (value) => createStaticSinglePromptResolution(DEPLOY_OPTIONS, "none", value);
|
|
1910
2278
|
const getElixirWebFrameworkChoice = (value) => makeChoice("Select Elixir web framework", WEB_FRAMEWORK_OPTIONS, "phoenix", value);
|
|
1911
2279
|
const getElixirOrmChoice = (value) => makeChoice("Select Elixir database layer", ORM_OPTIONS, "ecto-sql", value);
|
|
1912
2280
|
const getElixirAuthChoice = (value) => makeChoice("Select Elixir auth", AUTH_OPTIONS, "none", value);
|
|
@@ -3330,11 +3698,11 @@ async function getJavaLanguageChoice(javaLanguage) {
|
|
|
3330
3698
|
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
3331
3699
|
return response;
|
|
3332
3700
|
}
|
|
3333
|
-
function resolveJavaBuildToolPrompt(javaBuildTool) {
|
|
3334
|
-
return createStaticSinglePromptResolution(JAVA_BUILD_TOOL_PROMPT_OPTIONS, "maven", javaBuildTool);
|
|
3701
|
+
function resolveJavaBuildToolPrompt(javaBuildTool, javaLanguage) {
|
|
3702
|
+
return createStaticSinglePromptResolution(javaLanguage === "kotlin" ? JAVA_BUILD_TOOL_PROMPT_OPTIONS.filter((option) => option.value !== "none") : JAVA_BUILD_TOOL_PROMPT_OPTIONS, "maven", javaBuildTool);
|
|
3335
3703
|
}
|
|
3336
|
-
async function getJavaBuildToolChoice(javaBuildTool) {
|
|
3337
|
-
const resolution = resolveJavaBuildToolPrompt(javaBuildTool);
|
|
3704
|
+
async function getJavaBuildToolChoice(javaBuildTool, javaLanguage) {
|
|
3705
|
+
const resolution = resolveJavaBuildToolPrompt(javaBuildTool, javaLanguage);
|
|
3338
3706
|
if (!resolution.shouldPrompt) return resolution.autoValue ?? "none";
|
|
3339
3707
|
const response = await navigableSelect({
|
|
3340
3708
|
message: "Select Java build tool",
|
|
@@ -3344,11 +3712,11 @@ async function getJavaBuildToolChoice(javaBuildTool) {
|
|
|
3344
3712
|
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
3345
3713
|
return response;
|
|
3346
3714
|
}
|
|
3347
|
-
function resolveJavaOrmPrompt(javaOrm) {
|
|
3348
|
-
return createStaticSinglePromptResolution(JAVA_ORM_PROMPT_OPTIONS, "none", javaOrm);
|
|
3715
|
+
function resolveJavaOrmPrompt(javaOrm, javaLanguage) {
|
|
3716
|
+
return createStaticSinglePromptResolution(javaLanguage === "kotlin" ? JAVA_ORM_PROMPT_OPTIONS.filter((option) => option.value !== "jooq" && option.value !== "mybatis") : JAVA_ORM_PROMPT_OPTIONS, "none", javaOrm);
|
|
3349
3717
|
}
|
|
3350
|
-
async function getJavaOrmChoice(javaOrm) {
|
|
3351
|
-
const resolution = resolveJavaOrmPrompt(javaOrm);
|
|
3718
|
+
async function getJavaOrmChoice(javaOrm, javaLanguage) {
|
|
3719
|
+
const resolution = resolveJavaOrmPrompt(javaOrm, javaLanguage);
|
|
3352
3720
|
if (!resolution.shouldPrompt) return resolution.autoValue ?? "none";
|
|
3353
3721
|
const response = await navigableSelect({
|
|
3354
3722
|
message: "Select Java ORM/database layer",
|
|
@@ -3372,11 +3740,11 @@ async function getJavaAuthChoice(javaAuth) {
|
|
|
3372
3740
|
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
3373
3741
|
return response;
|
|
3374
3742
|
}
|
|
3375
|
-
function resolveJavaLibrariesPrompt(javaLibraries) {
|
|
3376
|
-
return createStaticMultiPromptResolution(JAVA_LIBRARY_PROMPT_OPTIONS, [], javaLibraries);
|
|
3743
|
+
function resolveJavaLibrariesPrompt(javaLibraries, javaLanguage) {
|
|
3744
|
+
return createStaticMultiPromptResolution(javaLanguage === "kotlin" ? JAVA_LIBRARY_PROMPT_OPTIONS.filter((option) => !types_exports.KOTLIN_DROPPED_JAVA_LIBRARIES.has(option.value)) : JAVA_LIBRARY_PROMPT_OPTIONS, [], javaLibraries);
|
|
3377
3745
|
}
|
|
3378
|
-
async function getJavaLibrariesChoice(javaLibraries) {
|
|
3379
|
-
const resolution = resolveJavaLibrariesPrompt(javaLibraries);
|
|
3746
|
+
async function getJavaLibrariesChoice(javaLibraries, javaLanguage) {
|
|
3747
|
+
const resolution = resolveJavaLibrariesPrompt(javaLibraries, javaLanguage);
|
|
3380
3748
|
if (!resolution.shouldPrompt) return resolution.autoValue ?? [];
|
|
3381
3749
|
const response = await navigableMultiselect({
|
|
3382
3750
|
message: "Select Java application libraries",
|
|
@@ -3388,11 +3756,11 @@ async function getJavaLibrariesChoice(javaLibraries) {
|
|
|
3388
3756
|
if (response.includes("none")) return [];
|
|
3389
3757
|
return response;
|
|
3390
3758
|
}
|
|
3391
|
-
function resolveJavaTestingLibrariesPrompt(javaTestingLibraries) {
|
|
3392
|
-
return createStaticMultiPromptResolution(JAVA_TESTING_LIBRARY_PROMPT_OPTIONS, ["junit5"], javaTestingLibraries);
|
|
3759
|
+
function resolveJavaTestingLibrariesPrompt(javaTestingLibraries, javaLanguage) {
|
|
3760
|
+
return createStaticMultiPromptResolution(javaLanguage === "kotlin" ? JAVA_TESTING_LIBRARY_PROMPT_OPTIONS.filter((option) => !types_exports.KOTLIN_UNSUPPORTED_JAVA_TESTING_LIBRARIES.has(option.value)) : JAVA_TESTING_LIBRARY_PROMPT_OPTIONS, ["junit5"], javaTestingLibraries);
|
|
3393
3761
|
}
|
|
3394
|
-
async function getJavaTestingLibrariesChoice(javaTestingLibraries) {
|
|
3395
|
-
const resolution = resolveJavaTestingLibrariesPrompt(javaTestingLibraries);
|
|
3762
|
+
async function getJavaTestingLibrariesChoice(javaTestingLibraries, javaLanguage) {
|
|
3763
|
+
const resolution = resolveJavaTestingLibrariesPrompt(javaTestingLibraries, javaLanguage);
|
|
3396
3764
|
if (!resolution.shouldPrompt) return resolution.autoValue ?? [];
|
|
3397
3765
|
const response = await navigableMultiselect({
|
|
3398
3766
|
message: "Select Java testing libraries",
|
|
@@ -3443,11 +3811,11 @@ const JAVA_LOGGING_PROMPT_OPTIONS = [
|
|
|
3443
3811
|
hint: "Spring Boot logging defaults"
|
|
3444
3812
|
}
|
|
3445
3813
|
];
|
|
3446
|
-
function resolveJavaApiPrompt(javaApi) {
|
|
3447
|
-
return createStaticSinglePromptResolution(JAVA_API_PROMPT_OPTIONS, "none", javaApi);
|
|
3814
|
+
function resolveJavaApiPrompt(javaApi, javaLanguage) {
|
|
3815
|
+
return createStaticSinglePromptResolution(javaLanguage === "kotlin" ? JAVA_API_PROMPT_OPTIONS.filter((option) => option.value !== "grpc" && option.value !== "openapi-generator") : JAVA_API_PROMPT_OPTIONS, "none", javaApi);
|
|
3448
3816
|
}
|
|
3449
|
-
async function getJavaApiChoice(javaApi) {
|
|
3450
|
-
const resolution = resolveJavaApiPrompt(javaApi);
|
|
3817
|
+
async function getJavaApiChoice(javaApi, javaLanguage) {
|
|
3818
|
+
const resolution = resolveJavaApiPrompt(javaApi, javaLanguage);
|
|
3451
3819
|
if (!resolution.shouldPrompt) return resolution.autoValue ?? "none";
|
|
3452
3820
|
const response = await navigableSelect({
|
|
3453
3821
|
message: "Select Java API layer",
|
|
@@ -3709,6 +4077,27 @@ async function promptMobileOption(options, defaultValue, selected, message) {
|
|
|
3709
4077
|
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
3710
4078
|
return response;
|
|
3711
4079
|
}
|
|
4080
|
+
function resolveMobileNavigationPrompt(mobileNavigation) {
|
|
4081
|
+
return createStaticSinglePromptResolution(MOBILE_NAVIGATION_OPTIONS, "expo-router", mobileNavigation);
|
|
4082
|
+
}
|
|
4083
|
+
function resolveMobileUIPrompt(mobileUI) {
|
|
4084
|
+
return createStaticSinglePromptResolution(MOBILE_UI_OPTIONS, "none", mobileUI);
|
|
4085
|
+
}
|
|
4086
|
+
function resolveMobileStoragePrompt(mobileStorage) {
|
|
4087
|
+
return createStaticSinglePromptResolution(MOBILE_STORAGE_OPTIONS, "none", mobileStorage);
|
|
4088
|
+
}
|
|
4089
|
+
function resolveMobileTestingPrompt(mobileTesting) {
|
|
4090
|
+
return createStaticSinglePromptResolution(MOBILE_TESTING_OPTIONS, "none", mobileTesting);
|
|
4091
|
+
}
|
|
4092
|
+
function resolveMobilePushPrompt(mobilePush) {
|
|
4093
|
+
return createStaticSinglePromptResolution(MOBILE_PUSH_OPTIONS, "none", mobilePush);
|
|
4094
|
+
}
|
|
4095
|
+
function resolveMobileOTAPrompt(mobileOTA) {
|
|
4096
|
+
return createStaticSinglePromptResolution(MOBILE_OTA_OPTIONS, "none", mobileOTA);
|
|
4097
|
+
}
|
|
4098
|
+
function resolveMobileDeepLinkingPrompt(mobileDeepLinking) {
|
|
4099
|
+
return createStaticSinglePromptResolution(MOBILE_DEEP_LINKING_OPTIONS, "expo-linking", mobileDeepLinking);
|
|
4100
|
+
}
|
|
3712
4101
|
function getMobileNavigationChoice(mobileNavigation) {
|
|
3713
4102
|
return promptMobileOption(MOBILE_NAVIGATION_OPTIONS, "expo-router", mobileNavigation, "Select mobile navigation");
|
|
3714
4103
|
}
|
|
@@ -5445,6 +5834,13 @@ function promptValue(value) {
|
|
|
5445
5834
|
if (isCancel$1(value) || isGoBack(value)) return exitCancelled("Operation cancelled");
|
|
5446
5835
|
return value;
|
|
5447
5836
|
}
|
|
5837
|
+
function hasMultiStackPromptFlags(flags) {
|
|
5838
|
+
return Object.keys(flags).some((key) => key !== "projectName" && key !== "projectDir" && key !== "relativePath");
|
|
5839
|
+
}
|
|
5840
|
+
async function scopedPromptValue(ecosystem, key, scope, selectedSectionIds, prompt) {
|
|
5841
|
+
if (!shouldAskConfigPromptKey(ecosystem, key, scope, selectedSectionIds)) return getDefaultPromptValue(key);
|
|
5842
|
+
return promptValue(await prompt());
|
|
5843
|
+
}
|
|
5448
5844
|
async function selectDatabaseConfig(flags) {
|
|
5449
5845
|
const database = promptValue(await getDatabaseChoice(flags.database, "hono", "bun"));
|
|
5450
5846
|
return {
|
|
@@ -5454,6 +5850,12 @@ async function selectDatabaseConfig(flags) {
|
|
|
5454
5850
|
}
|
|
5455
5851
|
async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relativePath) {
|
|
5456
5852
|
const baseConfig = getDefaultConfig();
|
|
5853
|
+
const configScope = !hasMultiStackPromptFlags(flags) ? promptValue(await getConfigScopeChoice()) : "full";
|
|
5854
|
+
const typeScriptSections = configScope === "custom" ? promptValue(await getConfigSectionsChoice("typescript", [], [
|
|
5855
|
+
"ui-styling",
|
|
5856
|
+
"deploy",
|
|
5857
|
+
"addons-examples"
|
|
5858
|
+
])) : [];
|
|
5457
5859
|
const frontend = promptValue(await navigableSelect({
|
|
5458
5860
|
message: "Select TypeScript web frontend",
|
|
5459
5861
|
options: WEB_FRONTEND_PROMPT_OPTIONS,
|
|
@@ -5461,8 +5863,8 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
|
|
|
5461
5863
|
}));
|
|
5462
5864
|
const frontendList = [frontend];
|
|
5463
5865
|
const astroIntegration = frontend === "astro" ? promptValue(await getAstroIntegrationChoice(flags.astroIntegration)) : void 0;
|
|
5464
|
-
const uiLibrary = hasWebStyling$1(frontendList) ?
|
|
5465
|
-
const shadcnOptions = uiLibrary === "shadcn-ui" ? promptValue(await getShadcnOptions({
|
|
5866
|
+
const uiLibrary = hasWebStyling$1(frontendList) ? await scopedPromptValue("typescript", "uiLibrary", configScope, typeScriptSections, () => getUILibraryChoice(flags.uiLibrary, frontendList, astroIntegration)) : "none";
|
|
5867
|
+
const shadcnOptions = uiLibrary === "shadcn-ui" ? shouldAskConfigPromptKey("typescript", "shadcnOptions", configScope, typeScriptSections) ? promptValue(await getShadcnOptions({
|
|
5466
5868
|
shadcnBase: flags.shadcnBase,
|
|
5467
5869
|
shadcnStyle: flags.shadcnStyle,
|
|
5468
5870
|
shadcnIconLibrary: flags.shadcnIconLibrary,
|
|
@@ -5470,9 +5872,10 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
|
|
|
5470
5872
|
shadcnBaseColor: flags.shadcnBaseColor,
|
|
5471
5873
|
shadcnFont: flags.shadcnFont,
|
|
5472
5874
|
shadcnRadius: flags.shadcnRadius
|
|
5473
|
-
})) : void 0;
|
|
5474
|
-
const cssFramework = hasWebStyling$1(frontendList) ?
|
|
5875
|
+
})) : getDefaultPromptValue("shadcnOptions") : void 0;
|
|
5876
|
+
const cssFramework = hasWebStyling$1(frontendList) ? await scopedPromptValue("typescript", "cssFramework", configScope, typeScriptSections, () => getCSSFrameworkChoice(flags.cssFramework, uiLibrary)) : "none";
|
|
5475
5877
|
const backendEcosystem = await selectBackendEcosystem();
|
|
5878
|
+
const backendSections = configScope === "custom" ? promptValue(await getConfigSectionsChoice(backendEcosystem)) : [];
|
|
5476
5879
|
const stackPartSpecs = [`frontend:typescript:${frontend}`];
|
|
5477
5880
|
const backendChoices = {};
|
|
5478
5881
|
let database = "none";
|
|
@@ -5487,14 +5890,14 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
|
|
|
5487
5890
|
const goOrm = database === "none" || goWebFramework === "none" ? "none" : promptValue(await getGoOrmChoice(flags.goOrm));
|
|
5488
5891
|
const goApi = goWebFramework === "none" ? "none" : promptValue(await getGoApiChoice(flags.goApi));
|
|
5489
5892
|
const goAuth = goWebFramework === "none" ? "none" : promptValue(await getGoAuthChoice(flags.goAuth));
|
|
5490
|
-
const goCli = goWebFramework === "none" ? "none" :
|
|
5491
|
-
const goLogging = goWebFramework === "none" ? "none" :
|
|
5492
|
-
const goTesting = goWebFramework === "none" ? [] :
|
|
5493
|
-
const goRealtime = goWebFramework === "none" ? "none" :
|
|
5494
|
-
const goMessageQueue = goWebFramework === "none" ? "none" :
|
|
5495
|
-
const goCaching = goWebFramework === "none" ? "none" :
|
|
5496
|
-
const goConfig = goWebFramework === "none" ? "none" :
|
|
5497
|
-
const goObservability = goWebFramework === "none" ? "none" :
|
|
5893
|
+
const goCli = goWebFramework === "none" ? "none" : await scopedPromptValue("go", "goCli", configScope, backendSections, () => getGoCliChoice(flags.goCli));
|
|
5894
|
+
const goLogging = goWebFramework === "none" ? "none" : await scopedPromptValue("go", "goLogging", configScope, backendSections, () => getGoLoggingChoice(flags.goLogging));
|
|
5895
|
+
const goTesting = goWebFramework === "none" ? [] : await scopedPromptValue("go", "goTesting", configScope, backendSections, () => getGoTestingChoice(flags.goTesting));
|
|
5896
|
+
const goRealtime = goWebFramework === "none" ? "none" : await scopedPromptValue("go", "goRealtime", configScope, backendSections, () => getGoRealtimeChoice(flags.goRealtime));
|
|
5897
|
+
const goMessageQueue = goWebFramework === "none" ? "none" : await scopedPromptValue("go", "goMessageQueue", configScope, backendSections, () => getGoMessageQueueChoice(flags.goMessageQueue));
|
|
5898
|
+
const goCaching = goWebFramework === "none" ? "none" : await scopedPromptValue("go", "goCaching", configScope, backendSections, () => getGoCachingChoice(flags.goCaching));
|
|
5899
|
+
const goConfig = goWebFramework === "none" ? "none" : await scopedPromptValue("go", "goConfig", configScope, backendSections, () => getGoConfigChoice(flags.goConfig));
|
|
5900
|
+
const goObservability = goWebFramework === "none" ? "none" : await scopedPromptValue("go", "goObservability", configScope, backendSections, () => getGoObservabilityChoice(flags.goObservability));
|
|
5498
5901
|
Object.assign(backendChoices, {
|
|
5499
5902
|
goWebFramework,
|
|
5500
5903
|
goOrm,
|
|
@@ -5531,15 +5934,15 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
|
|
|
5531
5934
|
const rustApi = rustWebFramework === "none" ? "none" : promptValue(await getRustApiChoice(flags.rustApi));
|
|
5532
5935
|
const rustAuth = rustWebFramework === "none" ? "none" : promptValue(await getRustAuthChoice(flags.rustAuth));
|
|
5533
5936
|
const rustFrontend = "none";
|
|
5534
|
-
const rustCli = rustWebFramework === "none" ? "none" :
|
|
5535
|
-
const rustLibraries = rustWebFramework === "none" ? [] :
|
|
5536
|
-
const rustLogging = rustWebFramework === "none" ? "none" :
|
|
5537
|
-
const rustErrorHandling =
|
|
5538
|
-
const rustCaching = rustWebFramework === "none" ? "none" :
|
|
5539
|
-
const rustRealtime = rustWebFramework === "none" ? "none" :
|
|
5540
|
-
const rustMessageQueue = rustWebFramework === "none" ? "none" :
|
|
5541
|
-
const rustObservability = rustWebFramework === "none" ? "none" :
|
|
5542
|
-
const rustTemplating = rustWebFramework === "none" ? "none" :
|
|
5937
|
+
const rustCli = rustWebFramework === "none" ? "none" : await scopedPromptValue("rust", "rustCli", configScope, backendSections, () => getRustCliChoice(flags.rustCli));
|
|
5938
|
+
const rustLibraries = rustWebFramework === "none" ? [] : await scopedPromptValue("rust", "rustLibraries", configScope, backendSections, () => getRustLibrariesChoice(flags.rustLibraries));
|
|
5939
|
+
const rustLogging = rustWebFramework === "none" ? "none" : await scopedPromptValue("rust", "rustLogging", configScope, backendSections, () => getRustLoggingChoice(flags.rustLogging));
|
|
5940
|
+
const rustErrorHandling = await scopedPromptValue("rust", "rustErrorHandling", configScope, backendSections, () => getRustErrorHandlingChoice(flags.rustErrorHandling));
|
|
5941
|
+
const rustCaching = rustWebFramework === "none" ? "none" : await scopedPromptValue("rust", "rustCaching", configScope, backendSections, () => getRustCachingChoice(flags.rustCaching));
|
|
5942
|
+
const rustRealtime = rustWebFramework === "none" ? "none" : await scopedPromptValue("rust", "rustRealtime", configScope, backendSections, () => getRustRealtimeChoice(flags.rustRealtime));
|
|
5943
|
+
const rustMessageQueue = rustWebFramework === "none" ? "none" : await scopedPromptValue("rust", "rustMessageQueue", configScope, backendSections, () => getRustMessageQueueChoice(flags.rustMessageQueue));
|
|
5944
|
+
const rustObservability = rustWebFramework === "none" ? "none" : await scopedPromptValue("rust", "rustObservability", configScope, backendSections, () => getRustObservabilityChoice(flags.rustObservability));
|
|
5945
|
+
const rustTemplating = rustWebFramework === "none" ? "none" : await scopedPromptValue("rust", "rustTemplating", configScope, backendSections, () => getRustTemplatingChoice(flags.rustTemplating));
|
|
5543
5946
|
Object.assign(backendChoices, {
|
|
5544
5947
|
rustWebFramework,
|
|
5545
5948
|
rustOrm,
|
|
@@ -5573,17 +5976,17 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
|
|
|
5573
5976
|
dbSetup = databaseConfig.dbSetup;
|
|
5574
5977
|
}
|
|
5575
5978
|
const pythonOrm = database === "none" || pythonWebFramework === "none" ? "none" : promptValue(await getPythonOrmChoice(flags.pythonOrm));
|
|
5576
|
-
const pythonValidation = pythonWebFramework === "none" ? "none" :
|
|
5577
|
-
const pythonAi = pythonWebFramework === "none" ? [] :
|
|
5979
|
+
const pythonValidation = pythonWebFramework === "none" ? "none" : await scopedPromptValue("python", "pythonValidation", configScope, backendSections, () => getPythonValidationChoice(flags.pythonValidation));
|
|
5980
|
+
const pythonAi = pythonWebFramework === "none" ? [] : await scopedPromptValue("python", "pythonAi", configScope, backendSections, () => getPythonAiChoice(flags.pythonAi));
|
|
5578
5981
|
const pythonAuth = pythonWebFramework === "none" ? "none" : promptValue(await getPythonAuthChoice(flags.pythonAuth));
|
|
5579
|
-
const pythonTaskQueue = pythonWebFramework === "none" ? "none" :
|
|
5580
|
-
const pythonGraphql = pythonWebFramework === "none" ? "none" :
|
|
5581
|
-
const pythonQuality = pythonWebFramework === "none" ? "none" :
|
|
5582
|
-
const pythonTesting = pythonWebFramework === "none" ? [] :
|
|
5583
|
-
const pythonCaching = pythonWebFramework === "none" ? "none" :
|
|
5584
|
-
const pythonRealtime = pythonWebFramework === "none" ? "none" :
|
|
5585
|
-
const pythonObservability = pythonWebFramework === "none" ? "none" :
|
|
5586
|
-
const pythonCli = pythonWebFramework === "none" ? [] :
|
|
5982
|
+
const pythonTaskQueue = pythonWebFramework === "none" ? "none" : await scopedPromptValue("python", "pythonTaskQueue", configScope, backendSections, () => getPythonTaskQueueChoice(flags.pythonTaskQueue));
|
|
5983
|
+
const pythonGraphql = pythonWebFramework === "none" ? "none" : await scopedPromptValue("python", "pythonGraphql", configScope, backendSections, () => getPythonGraphqlChoice(flags.pythonGraphql));
|
|
5984
|
+
const pythonQuality = pythonWebFramework === "none" ? "none" : await scopedPromptValue("python", "pythonQuality", configScope, backendSections, () => getPythonQualityChoice(flags.pythonQuality));
|
|
5985
|
+
const pythonTesting = pythonWebFramework === "none" ? [] : await scopedPromptValue("python", "pythonTesting", configScope, backendSections, () => getPythonTestingChoice(flags.pythonTesting));
|
|
5986
|
+
const pythonCaching = pythonWebFramework === "none" ? "none" : await scopedPromptValue("python", "pythonCaching", configScope, backendSections, () => getPythonCachingChoice(flags.pythonCaching));
|
|
5987
|
+
const pythonRealtime = pythonWebFramework === "none" ? "none" : await scopedPromptValue("python", "pythonRealtime", configScope, backendSections, () => getPythonRealtimeChoice(flags.pythonRealtime));
|
|
5988
|
+
const pythonObservability = pythonWebFramework === "none" ? "none" : await scopedPromptValue("python", "pythonObservability", configScope, backendSections, () => getPythonObservabilityChoice(flags.pythonObservability));
|
|
5989
|
+
const pythonCli = pythonWebFramework === "none" ? [] : await scopedPromptValue("python", "pythonCli", configScope, backendSections, () => getPythonCliChoice(flags.pythonCli));
|
|
5587
5990
|
Object.assign(backendChoices, {
|
|
5588
5991
|
pythonWebFramework,
|
|
5589
5992
|
pythonOrm,
|
|
@@ -5612,19 +6015,21 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
|
|
|
5612
6015
|
}
|
|
5613
6016
|
if (backendEcosystem === "java") {
|
|
5614
6017
|
const javaWebFramework = promptValue(await getJavaWebFrameworkChoice(flags.javaWebFramework));
|
|
5615
|
-
const
|
|
6018
|
+
const javaLanguage = javaWebFramework !== "spring-boot" ? "java" : flags.javaLanguage !== void 0 ? promptValue(await getJavaLanguageChoice(flags.javaLanguage)) : flags.javaWebFramework !== void 0 ? "java" : promptValue(await getJavaLanguageChoice(flags.javaLanguage));
|
|
6019
|
+
const javaBuildTool = promptValue(await getJavaBuildToolChoice(flags.javaBuildTool, javaLanguage));
|
|
5616
6020
|
if (javaWebFramework !== "none" && javaBuildTool !== "none") {
|
|
5617
6021
|
const databaseConfig = await selectDatabaseConfig(flags);
|
|
5618
6022
|
database = databaseConfig.database;
|
|
5619
6023
|
dbSetup = databaseConfig.dbSetup;
|
|
5620
6024
|
}
|
|
5621
|
-
const javaOrm = database === "none" || javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? "none" : promptValue(await getJavaOrmChoice(flags.javaOrm));
|
|
6025
|
+
const javaOrm = database === "none" || javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? "none" : promptValue(await getJavaOrmChoice(flags.javaOrm, javaLanguage));
|
|
5622
6026
|
const javaAuth = javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? "none" : promptValue(await getJavaAuthChoice(flags.javaAuth));
|
|
5623
|
-
const javaLibraries = javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? [] :
|
|
5624
|
-
const javaTestingLibraries =
|
|
5625
|
-
const javaApi = javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? "none" : promptValue(await getJavaApiChoice(flags.javaApi));
|
|
5626
|
-
const javaLogging = javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? "none" :
|
|
6027
|
+
const javaLibraries = javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? [] : await scopedPromptValue("java", "javaLibraries", configScope, backendSections, () => getJavaLibrariesChoice(flags.javaLibraries, javaLanguage));
|
|
6028
|
+
const javaTestingLibraries = await scopedPromptValue("java", "javaTestingLibraries", configScope, backendSections, () => getJavaTestingLibrariesChoice(flags.javaTestingLibraries, javaLanguage));
|
|
6029
|
+
const javaApi = javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? "none" : promptValue(await getJavaApiChoice(flags.javaApi, javaLanguage));
|
|
6030
|
+
const javaLogging = javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? "none" : await scopedPromptValue("java", "javaLogging", configScope, backendSections, () => getJavaLoggingChoice(flags.javaLogging));
|
|
5627
6031
|
Object.assign(backendChoices, {
|
|
6032
|
+
javaLanguage,
|
|
5628
6033
|
javaWebFramework,
|
|
5629
6034
|
javaBuildTool,
|
|
5630
6035
|
javaOrm,
|
|
@@ -5635,6 +6040,7 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
|
|
|
5635
6040
|
javaTestingLibraries
|
|
5636
6041
|
});
|
|
5637
6042
|
if (javaWebFramework !== "none") stackPartSpecs.push(`backend:java:${javaWebFramework}`);
|
|
6043
|
+
if (javaWebFramework !== "none") stackPartSpecs.push(`backend.language:java:${javaLanguage}`);
|
|
5638
6044
|
if (javaOrm !== "none") stackPartSpecs.push(`backend.orm:java:${javaOrm}`);
|
|
5639
6045
|
if (javaAuth !== "none") stackPartSpecs.push(`backend.auth:java:${javaAuth}`);
|
|
5640
6046
|
if (javaApi !== "none") stackPartSpecs.push(`backend.api:java:${javaApi}`);
|
|
@@ -5650,13 +6056,13 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
|
|
|
5650
6056
|
const dotnetOrm = database === "none" || dotnetWebFramework === "none" ? "none" : promptValue(await getDotnetOrmChoice(flags.dotnetOrm));
|
|
5651
6057
|
const dotnetAuth = dotnetWebFramework === "none" ? "none" : promptValue(await getDotnetAuthChoice(flags.dotnetAuth));
|
|
5652
6058
|
const dotnetApi = dotnetWebFramework === "none" ? "none" : promptValue(await getDotnetApiChoice(flags.dotnetApi));
|
|
5653
|
-
const dotnetTesting = dotnetWebFramework === "none" ? [] :
|
|
5654
|
-
const dotnetJobQueue = dotnetWebFramework === "none" ? "none" :
|
|
5655
|
-
const dotnetRealtime = dotnetWebFramework === "none" ? "none" :
|
|
5656
|
-
const dotnetObservability = dotnetWebFramework === "none" ? [] :
|
|
5657
|
-
const dotnetValidation = dotnetWebFramework === "none" ? "none" :
|
|
5658
|
-
const dotnetCaching = dotnetWebFramework === "none" ? "none" :
|
|
5659
|
-
const dotnetDeploy = dotnetWebFramework === "none" ? "none" :
|
|
6059
|
+
const dotnetTesting = dotnetWebFramework === "none" ? [] : await scopedPromptValue("dotnet", "dotnetTesting", configScope, backendSections, () => getDotnetTestingChoice(flags.dotnetTesting));
|
|
6060
|
+
const dotnetJobQueue = dotnetWebFramework === "none" ? "none" : await scopedPromptValue("dotnet", "dotnetJobQueue", configScope, backendSections, () => getDotnetJobQueueChoice(flags.dotnetJobQueue));
|
|
6061
|
+
const dotnetRealtime = dotnetWebFramework === "none" ? "none" : await scopedPromptValue("dotnet", "dotnetRealtime", configScope, backendSections, () => getDotnetRealtimeChoice(flags.dotnetRealtime));
|
|
6062
|
+
const dotnetObservability = dotnetWebFramework === "none" ? [] : await scopedPromptValue("dotnet", "dotnetObservability", configScope, backendSections, () => getDotnetObservabilityChoice(flags.dotnetObservability));
|
|
6063
|
+
const dotnetValidation = dotnetWebFramework === "none" ? "none" : await scopedPromptValue("dotnet", "dotnetValidation", configScope, backendSections, () => getDotnetValidationChoice(flags.dotnetValidation));
|
|
6064
|
+
const dotnetCaching = dotnetWebFramework === "none" ? "none" : await scopedPromptValue("dotnet", "dotnetCaching", configScope, backendSections, () => getDotnetCachingChoice(flags.dotnetCaching));
|
|
6065
|
+
const dotnetDeploy = dotnetWebFramework === "none" ? "none" : await scopedPromptValue("dotnet", "dotnetDeploy", configScope, backendSections, () => getDotnetDeployChoice(flags.dotnetDeploy));
|
|
5660
6066
|
Object.assign(backendChoices, {
|
|
5661
6067
|
dotnetWebFramework,
|
|
5662
6068
|
dotnetOrm,
|
|
@@ -5692,18 +6098,18 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
|
|
|
5692
6098
|
const elixirOrm = database === "none" || elixirWebFramework === "none" ? "none" : promptValue(await getElixirOrmChoice(flags.elixirOrm));
|
|
5693
6099
|
const elixirAuth = elixirWebFramework === "none" ? "none" : promptValue(await getElixirAuthChoice(flags.elixirAuth));
|
|
5694
6100
|
const elixirApi = elixirWebFramework === "none" ? "none" : promptValue(await getElixirApiChoice(flags.elixirApi));
|
|
5695
|
-
const elixirRealtime = elixirWebFramework === "none" ? "none" :
|
|
5696
|
-
const elixirJobs = elixirWebFramework === "none" ? "none" :
|
|
5697
|
-
const elixirValidation = elixirWebFramework === "none" ? "none" :
|
|
5698
|
-
const elixirHttp = elixirWebFramework === "none" ? "none" :
|
|
5699
|
-
const elixirJson = elixirWebFramework === "none" ? "none" :
|
|
5700
|
-
const elixirEmail = elixirWebFramework === "none" ? "none" :
|
|
5701
|
-
const elixirCaching = elixirWebFramework === "none" ? "none" :
|
|
5702
|
-
const elixirObservability = elixirWebFramework === "none" ? "none" :
|
|
5703
|
-
const elixirTesting = elixirWebFramework === "none" ? "none" :
|
|
5704
|
-
const elixirQuality = elixirWebFramework === "none" ? "none" :
|
|
5705
|
-
const elixirDeploy = elixirWebFramework === "none" ? "none" :
|
|
5706
|
-
const elixirLibraries = elixirWebFramework === "none" ? [] :
|
|
6101
|
+
const elixirRealtime = elixirWebFramework === "none" ? "none" : await scopedPromptValue("elixir", "elixirRealtime", configScope, backendSections, () => getElixirRealtimeChoice(flags.elixirRealtime));
|
|
6102
|
+
const elixirJobs = elixirWebFramework === "none" ? "none" : await scopedPromptValue("elixir", "elixirJobs", configScope, backendSections, () => getElixirJobsChoice(flags.elixirJobs));
|
|
6103
|
+
const elixirValidation = elixirWebFramework === "none" ? "none" : await scopedPromptValue("elixir", "elixirValidation", configScope, backendSections, () => getElixirValidationChoice(flags.elixirValidation));
|
|
6104
|
+
const elixirHttp = elixirWebFramework === "none" ? "none" : await scopedPromptValue("elixir", "elixirHttp", configScope, backendSections, () => getElixirHttpChoice(flags.elixirHttp));
|
|
6105
|
+
const elixirJson = elixirWebFramework === "none" ? "none" : await scopedPromptValue("elixir", "elixirJson", configScope, backendSections, () => getElixirJsonChoice(flags.elixirJson));
|
|
6106
|
+
const elixirEmail = elixirWebFramework === "none" ? "none" : await scopedPromptValue("elixir", "elixirEmail", configScope, backendSections, () => getElixirEmailChoice(flags.elixirEmail));
|
|
6107
|
+
const elixirCaching = elixirWebFramework === "none" ? "none" : await scopedPromptValue("elixir", "elixirCaching", configScope, backendSections, () => getElixirCachingChoice(flags.elixirCaching));
|
|
6108
|
+
const elixirObservability = elixirWebFramework === "none" ? "none" : await scopedPromptValue("elixir", "elixirObservability", configScope, backendSections, () => getElixirObservabilityChoice(flags.elixirObservability));
|
|
6109
|
+
const elixirTesting = elixirWebFramework === "none" ? "none" : await scopedPromptValue("elixir", "elixirTesting", configScope, backendSections, () => getElixirTestingChoice(flags.elixirTesting));
|
|
6110
|
+
const elixirQuality = elixirWebFramework === "none" ? "none" : await scopedPromptValue("elixir", "elixirQuality", configScope, backendSections, () => getElixirQualityChoice(flags.elixirQuality));
|
|
6111
|
+
const elixirDeploy = elixirWebFramework === "none" ? "none" : await scopedPromptValue("elixir", "elixirDeploy", configScope, backendSections, () => getElixirDeployChoice(flags.elixirDeploy));
|
|
6112
|
+
const elixirLibraries = elixirWebFramework === "none" ? [] : await scopedPromptValue("elixir", "elixirLibraries", configScope, backendSections, () => getElixirLibrariesChoice(flags.elixirLibraries));
|
|
5707
6113
|
Object.assign(backendChoices, {
|
|
5708
6114
|
elixirWebFramework,
|
|
5709
6115
|
elixirOrm,
|
|
@@ -5738,9 +6144,9 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
|
|
|
5738
6144
|
if (database !== "none") stackPartSpecs.push(`database:universal:${database}`);
|
|
5739
6145
|
const stackParts = (0, types_exports.parseStackPartSpecs)(stackPartSpecs, "selected");
|
|
5740
6146
|
const graphPartial = (0, types_exports.stackPartsToLegacyProjectConfigPartial)(stackParts);
|
|
5741
|
-
const addons =
|
|
5742
|
-
const webDeploy =
|
|
5743
|
-
const serverDeploy = await selectServerDeployment(flags.serverDeploy);
|
|
6147
|
+
const addons = await scopedPromptValue("typescript", "addons", configScope, typeScriptSections, () => getAddonsChoice(flags.addons, frontendList, "none", "none", "bun"));
|
|
6148
|
+
const webDeploy = await scopedPromptValue("typescript", "webDeploy", configScope, typeScriptSections, () => getDeploymentChoice(flags.webDeploy, "bun", "none", frontendList));
|
|
6149
|
+
const serverDeploy = shouldAskConfigPromptKey("typescript", "serverDeploy", configScope, typeScriptSections) ? await selectServerDeployment(flags.serverDeploy) : getDefaultPromptValue("serverDeploy");
|
|
5744
6150
|
const aiDocs = promptValue(await getAiDocsChoice(flags.aiDocs));
|
|
5745
6151
|
const git = promptValue(await getGitChoice(flags.git));
|
|
5746
6152
|
const packageManager = promptValue(await getPackageManagerChoice(flags.packageManager));
|
|
@@ -6325,192 +6731,16 @@ async function getRuntimeChoice(runtime, backend) {
|
|
|
6325
6731
|
}
|
|
6326
6732
|
|
|
6327
6733
|
//#endregion
|
|
6328
|
-
//#region src/prompts/
|
|
6329
|
-
|
|
6330
|
-
{
|
|
6331
|
-
value: "meilisearch",
|
|
6332
|
-
label: "Meilisearch",
|
|
6333
|
-
hint: "Lightning-fast search engine with typo tolerance"
|
|
6334
|
-
},
|
|
6335
|
-
{
|
|
6336
|
-
value: "typesense",
|
|
6337
|
-
label: "Typesense",
|
|
6338
|
-
hint: "Fast, typo-tolerant search with built-in vector search"
|
|
6339
|
-
},
|
|
6340
|
-
{
|
|
6341
|
-
value: "elasticsearch",
|
|
6342
|
-
label: "Elasticsearch",
|
|
6343
|
-
hint: "Distributed search and analytics engine with local and cloud deployments"
|
|
6344
|
-
},
|
|
6345
|
-
{
|
|
6346
|
-
value: "opensearch",
|
|
6347
|
-
label: "OpenSearch",
|
|
6348
|
-
hint: "Open-source search and analytics suite compatible with Elasticsearch APIs"
|
|
6349
|
-
},
|
|
6350
|
-
{
|
|
6351
|
-
value: "algolia",
|
|
6352
|
-
label: "Algolia",
|
|
6353
|
-
hint: "Hosted search API with instant results, typo tolerance, and analytics"
|
|
6354
|
-
},
|
|
6355
|
-
{
|
|
6356
|
-
value: "none",
|
|
6357
|
-
label: "None",
|
|
6358
|
-
hint: "Skip search engine setup"
|
|
6359
|
-
}
|
|
6360
|
-
];
|
|
6361
|
-
const NON_TYPESCRIPT_SEARCH_PROMPT_OPTIONS = SEARCH_PROMPT_OPTIONS.filter((option) => option.value === "meilisearch" || option.value === "none");
|
|
6362
|
-
const PYTHON_SEARCH_PROMPT_OPTIONS = SEARCH_PROMPT_OPTIONS.filter((option) => option.value === "meilisearch" || option.value === "elasticsearch" || option.value === "none");
|
|
6363
|
-
const GO_SEARCH_PROMPT_OPTIONS = [
|
|
6364
|
-
{
|
|
6365
|
-
value: "meilisearch",
|
|
6366
|
-
label: "Meilisearch",
|
|
6367
|
-
hint: "Lightning-fast search engine with typo tolerance"
|
|
6368
|
-
},
|
|
6369
|
-
{
|
|
6370
|
-
value: "bleve",
|
|
6371
|
-
label: "Bleve",
|
|
6372
|
-
hint: "Embedded, server-less full-text search for Go (no external service)"
|
|
6373
|
-
},
|
|
6374
|
-
{
|
|
6375
|
-
value: "none",
|
|
6376
|
-
label: "None",
|
|
6377
|
-
hint: "Skip search engine setup"
|
|
6378
|
-
}
|
|
6379
|
-
];
|
|
6380
|
-
function resolveSearchPrompt(context = {}) {
|
|
6381
|
-
if (context.ecosystem === "react-native" || context.ecosystem === "elixir") return {
|
|
6734
|
+
//#region src/prompts/state-management.ts
|
|
6735
|
+
function resolveStateManagementPrompt(context = {}) {
|
|
6736
|
+
if (context.stateManagement !== void 0) return {
|
|
6382
6737
|
shouldPrompt: false,
|
|
6383
6738
|
mode: "single",
|
|
6384
6739
|
options: [],
|
|
6385
|
-
autoValue:
|
|
6740
|
+
autoValue: context.stateManagement
|
|
6386
6741
|
};
|
|
6387
|
-
const
|
|
6388
|
-
if (
|
|
6389
|
-
shouldPrompt: false,
|
|
6390
|
-
mode: "single",
|
|
6391
|
-
options: [],
|
|
6392
|
-
autoValue: "none"
|
|
6393
|
-
};
|
|
6394
|
-
return context.search !== void 0 ? {
|
|
6395
|
-
shouldPrompt: false,
|
|
6396
|
-
mode: "single",
|
|
6397
|
-
options,
|
|
6398
|
-
autoValue: context.search
|
|
6399
|
-
} : {
|
|
6400
|
-
shouldPrompt: true,
|
|
6401
|
-
mode: "single",
|
|
6402
|
-
options,
|
|
6403
|
-
initialValue: "none"
|
|
6404
|
-
};
|
|
6405
|
-
}
|
|
6406
|
-
async function getSearchChoice(search, backend, ecosystem) {
|
|
6407
|
-
const resolution = resolveSearchPrompt({
|
|
6408
|
-
search,
|
|
6409
|
-
backend,
|
|
6410
|
-
ecosystem
|
|
6411
|
-
});
|
|
6412
|
-
if (!resolution.shouldPrompt) return resolution.autoValue ?? "none";
|
|
6413
|
-
const response = await navigableSelect({
|
|
6414
|
-
message: "Select search engine",
|
|
6415
|
-
options: resolution.options,
|
|
6416
|
-
initialValue: resolution.initialValue
|
|
6417
|
-
});
|
|
6418
|
-
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
6419
|
-
return response;
|
|
6420
|
-
}
|
|
6421
|
-
|
|
6422
|
-
//#endregion
|
|
6423
|
-
//#region src/prompts/vector-db.ts
|
|
6424
|
-
const VECTOR_DB_PROMPT_OPTIONS = [
|
|
6425
|
-
{
|
|
6426
|
-
value: "pgvector",
|
|
6427
|
-
label: "pgvector",
|
|
6428
|
-
hint: "Self-hosted Postgres + pgvector extension for embeddings"
|
|
6429
|
-
},
|
|
6430
|
-
{
|
|
6431
|
-
value: "qdrant",
|
|
6432
|
-
label: "Qdrant",
|
|
6433
|
-
hint: "High-performance open-source vector database"
|
|
6434
|
-
},
|
|
6435
|
-
{
|
|
6436
|
-
value: "chroma",
|
|
6437
|
-
label: "Chroma",
|
|
6438
|
-
hint: "Lightweight open-source embedding database"
|
|
6439
|
-
},
|
|
6440
|
-
{
|
|
6441
|
-
value: "pinecone",
|
|
6442
|
-
label: "Pinecone",
|
|
6443
|
-
hint: "Fully managed serverless vector database"
|
|
6444
|
-
},
|
|
6445
|
-
{
|
|
6446
|
-
value: "none",
|
|
6447
|
-
label: "None",
|
|
6448
|
-
hint: "Skip vector database setup"
|
|
6449
|
-
}
|
|
6450
|
-
];
|
|
6451
|
-
/**
|
|
6452
|
-
* Vector DB is a TypeScript-ecosystem feature backed by a standalone server.
|
|
6453
|
-
* Every provider (including pgvector via a dedicated Postgres instance) is a
|
|
6454
|
-
* separate service, so there is no dependency on the primary database choice.
|
|
6455
|
-
*/
|
|
6456
|
-
function resolveVectorDbPrompt(context = {}) {
|
|
6457
|
-
const skip = () => ({
|
|
6458
|
-
shouldPrompt: false,
|
|
6459
|
-
mode: "single",
|
|
6460
|
-
options: [],
|
|
6461
|
-
autoValue: "none"
|
|
6462
|
-
});
|
|
6463
|
-
if (context.ecosystem && context.ecosystem !== "typescript") return skip();
|
|
6464
|
-
if (context.backend === "none" || context.backend === "convex") return skip();
|
|
6465
|
-
return context.vectorDb !== void 0 ? {
|
|
6466
|
-
shouldPrompt: false,
|
|
6467
|
-
mode: "single",
|
|
6468
|
-
options: VECTOR_DB_PROMPT_OPTIONS,
|
|
6469
|
-
autoValue: context.vectorDb
|
|
6470
|
-
} : {
|
|
6471
|
-
shouldPrompt: true,
|
|
6472
|
-
mode: "single",
|
|
6473
|
-
options: VECTOR_DB_PROMPT_OPTIONS,
|
|
6474
|
-
initialValue: "none"
|
|
6475
|
-
};
|
|
6476
|
-
}
|
|
6477
|
-
async function getVectorDbChoice(vectorDb, backend, ecosystem) {
|
|
6478
|
-
const resolution = resolveVectorDbPrompt({
|
|
6479
|
-
vectorDb,
|
|
6480
|
-
backend,
|
|
6481
|
-
ecosystem
|
|
6482
|
-
});
|
|
6483
|
-
if (!resolution.shouldPrompt) return resolution.autoValue ?? "none";
|
|
6484
|
-
const response = await navigableSelect({
|
|
6485
|
-
message: "Select vector database",
|
|
6486
|
-
options: resolution.options,
|
|
6487
|
-
initialValue: resolution.initialValue
|
|
6488
|
-
});
|
|
6489
|
-
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
6490
|
-
return response;
|
|
6491
|
-
}
|
|
6492
|
-
|
|
6493
|
-
//#endregion
|
|
6494
|
-
//#region src/prompts/server-deploy.ts
|
|
6495
|
-
async function getServerDeploymentChoice(deployment, runtime, backend, _webDeploy) {
|
|
6496
|
-
if (deployment !== void 0) return deployment;
|
|
6497
|
-
if (backend === "none" || backend === "convex") return "none";
|
|
6498
|
-
if (backend !== "hono") return "none";
|
|
6499
|
-
if (runtime === "workers") return "cloudflare";
|
|
6500
|
-
return "none";
|
|
6501
|
-
}
|
|
6502
|
-
|
|
6503
|
-
//#endregion
|
|
6504
|
-
//#region src/prompts/state-management.ts
|
|
6505
|
-
function resolveStateManagementPrompt(context = {}) {
|
|
6506
|
-
if (context.stateManagement !== void 0) return {
|
|
6507
|
-
shouldPrompt: false,
|
|
6508
|
-
mode: "single",
|
|
6509
|
-
options: [],
|
|
6510
|
-
autoValue: context.stateManagement
|
|
6511
|
-
};
|
|
6512
|
-
const { web } = splitFrontends$1(context.frontends);
|
|
6513
|
-
if (web.length === 0) return {
|
|
6742
|
+
const { web } = splitFrontends$1(context.frontends);
|
|
6743
|
+
if (web.length === 0) return {
|
|
6514
6744
|
shouldPrompt: false,
|
|
6515
6745
|
mode: "single",
|
|
6516
6746
|
options: [],
|
|
@@ -6700,14 +6930,1043 @@ async function getValidationChoice(validation) {
|
|
|
6700
6930
|
return response;
|
|
6701
6931
|
}
|
|
6702
6932
|
|
|
6933
|
+
//#endregion
|
|
6934
|
+
//#region src/prompts/prompt-resolver-registry.ts
|
|
6935
|
+
const PROMPT_RESOLVER_REGISTRY = {
|
|
6936
|
+
frontend: {
|
|
6937
|
+
schemaValues: types_exports.FRONTEND_VALUES,
|
|
6938
|
+
resolve: resolveFrontendPrompt,
|
|
6939
|
+
coverageContexts: [{ backend: "hono" }, { frontendOptions: ["none"] }]
|
|
6940
|
+
},
|
|
6941
|
+
backend: {
|
|
6942
|
+
schemaValues: types_exports.BACKEND_VALUES,
|
|
6943
|
+
resolve: resolveBackendPrompt,
|
|
6944
|
+
coverageContexts: [{ frontends: ["next"] }]
|
|
6945
|
+
},
|
|
6946
|
+
ai: {
|
|
6947
|
+
schemaValues: types_exports.AI_VALUES,
|
|
6948
|
+
resolve: ({ value } = {}) => resolveAIPrompt(value),
|
|
6949
|
+
coverageContexts: [{}]
|
|
6950
|
+
},
|
|
6951
|
+
animation: {
|
|
6952
|
+
schemaValues: types_exports.ANIMATION_VALUES,
|
|
6953
|
+
resolve: resolveAnimationPrompt,
|
|
6954
|
+
coverageContexts: [{ frontends: ["react-vite"] }]
|
|
6955
|
+
},
|
|
6956
|
+
api: {
|
|
6957
|
+
schemaValues: types_exports.API_VALUES,
|
|
6958
|
+
resolve: resolveApiPrompt,
|
|
6959
|
+
coverageContexts: [{
|
|
6960
|
+
frontend: ["next"],
|
|
6961
|
+
backend: "hono"
|
|
6962
|
+
}, { backend: "convex" }]
|
|
6963
|
+
},
|
|
6964
|
+
auth: {
|
|
6965
|
+
schemaValues: types_exports.AUTH_VALUES,
|
|
6966
|
+
resolve: resolveAuthPrompt,
|
|
6967
|
+
coverageContexts: [{
|
|
6968
|
+
ecosystem: "typescript",
|
|
6969
|
+
backend: "self",
|
|
6970
|
+
frontend: ["next"]
|
|
6971
|
+
}, {
|
|
6972
|
+
ecosystem: "go",
|
|
6973
|
+
backend: "none",
|
|
6974
|
+
frontend: []
|
|
6975
|
+
}]
|
|
6976
|
+
},
|
|
6977
|
+
caching: {
|
|
6978
|
+
schemaValues: types_exports.CACHING_VALUES,
|
|
6979
|
+
resolve: resolveCachingPrompt,
|
|
6980
|
+
coverageContexts: [{ backend: "hono" }, { backend: "none" }]
|
|
6981
|
+
},
|
|
6982
|
+
rateLimit: {
|
|
6983
|
+
schemaValues: types_exports.RATE_LIMIT_VALUES,
|
|
6984
|
+
resolve: resolveRateLimitPrompt,
|
|
6985
|
+
coverageContexts: [{ backend: "hono" }, { backend: "none" }]
|
|
6986
|
+
},
|
|
6987
|
+
cms: {
|
|
6988
|
+
schemaValues: types_exports.CMS_VALUES,
|
|
6989
|
+
resolve: resolveCMSPrompt,
|
|
6990
|
+
coverageContexts: [{ backend: "hono" }, { backend: "none" }]
|
|
6991
|
+
},
|
|
6992
|
+
cssFramework: {
|
|
6993
|
+
schemaValues: types_exports.CSS_FRAMEWORK_VALUES,
|
|
6994
|
+
resolve: resolveCSSFrameworkPrompt,
|
|
6995
|
+
coverageContexts: [{}, { uiLibrary: "radix-ui" }]
|
|
6996
|
+
},
|
|
6997
|
+
database: {
|
|
6998
|
+
schemaValues: types_exports.DATABASE_VALUES,
|
|
6999
|
+
resolve: resolveDatabasePrompt,
|
|
7000
|
+
coverageContexts: [{
|
|
7001
|
+
backend: "hono",
|
|
7002
|
+
runtime: "node"
|
|
7003
|
+
}, { backend: "none" }]
|
|
7004
|
+
},
|
|
7005
|
+
dbSetup: {
|
|
7006
|
+
schemaValues: types_exports.DATABASE_SETUP_VALUES,
|
|
7007
|
+
resolve: resolveDBSetupPrompt,
|
|
7008
|
+
coverageContexts: [
|
|
7009
|
+
{
|
|
7010
|
+
databaseType: "sqlite",
|
|
7011
|
+
runtime: "workers"
|
|
7012
|
+
},
|
|
7013
|
+
{ databaseType: "postgres" },
|
|
7014
|
+
{ databaseType: "mongodb" },
|
|
7015
|
+
{ databaseType: "redis" }
|
|
7016
|
+
]
|
|
7017
|
+
},
|
|
7018
|
+
email: {
|
|
7019
|
+
schemaValues: types_exports.EMAIL_VALUES,
|
|
7020
|
+
resolve: resolveEmailPrompt,
|
|
7021
|
+
coverageContexts: [{ backend: "hono" }, { backend: "none" }]
|
|
7022
|
+
},
|
|
7023
|
+
fileUpload: {
|
|
7024
|
+
schemaValues: types_exports.FILE_UPLOAD_VALUES,
|
|
7025
|
+
resolve: resolveFileUploadPrompt,
|
|
7026
|
+
coverageContexts: [{ backend: "hono" }, { backend: "none" }]
|
|
7027
|
+
},
|
|
7028
|
+
forms: {
|
|
7029
|
+
schemaValues: types_exports.FORMS_VALUES,
|
|
7030
|
+
resolve: resolveFormsPrompt,
|
|
7031
|
+
coverageContexts: [{ frontends: ["react-vite"] }, { frontends: ["solid"] }]
|
|
7032
|
+
},
|
|
7033
|
+
jobQueue: {
|
|
7034
|
+
schemaValues: types_exports.JOB_QUEUE_VALUES,
|
|
7035
|
+
resolve: resolveJobQueuePrompt,
|
|
7036
|
+
coverageContexts: [{ backend: "hono" }, { backend: "none" }]
|
|
7037
|
+
},
|
|
7038
|
+
logging: {
|
|
7039
|
+
schemaValues: types_exports.LOGGING_VALUES,
|
|
7040
|
+
resolve: resolveLoggingPrompt,
|
|
7041
|
+
coverageContexts: [{ backend: "hono" }, { backend: "none" }]
|
|
7042
|
+
},
|
|
7043
|
+
observability: {
|
|
7044
|
+
schemaValues: types_exports.OBSERVABILITY_VALUES,
|
|
7045
|
+
resolve: resolveObservabilityPrompt,
|
|
7046
|
+
coverageContexts: [{ backend: "hono" }, { backend: "none" }]
|
|
7047
|
+
},
|
|
7048
|
+
orm: {
|
|
7049
|
+
schemaValues: types_exports.ORM_VALUES,
|
|
7050
|
+
resolve: resolveORMPrompt,
|
|
7051
|
+
coverageContexts: [
|
|
7052
|
+
{
|
|
7053
|
+
hasDatabase: true,
|
|
7054
|
+
database: "postgres",
|
|
7055
|
+
runtime: "node"
|
|
7056
|
+
},
|
|
7057
|
+
{
|
|
7058
|
+
hasDatabase: true,
|
|
7059
|
+
database: "mongodb"
|
|
7060
|
+
},
|
|
7061
|
+
{ hasDatabase: false }
|
|
7062
|
+
]
|
|
7063
|
+
},
|
|
7064
|
+
payments: {
|
|
7065
|
+
schemaValues: types_exports.PAYMENTS_VALUES,
|
|
7066
|
+
resolve: resolvePaymentsPrompt,
|
|
7067
|
+
coverageContexts: [{
|
|
7068
|
+
auth: "better-auth",
|
|
7069
|
+
backend: "hono",
|
|
7070
|
+
frontends: ["next"]
|
|
7071
|
+
}, {
|
|
7072
|
+
auth: "better-auth",
|
|
7073
|
+
backend: "hono",
|
|
7074
|
+
frontends: ["native-bare"]
|
|
7075
|
+
}]
|
|
7076
|
+
},
|
|
7077
|
+
realtime: {
|
|
7078
|
+
schemaValues: types_exports.REALTIME_VALUES,
|
|
7079
|
+
resolve: resolveRealtimePrompt,
|
|
7080
|
+
coverageContexts: [{ backend: "hono" }, { backend: "none" }]
|
|
7081
|
+
},
|
|
7082
|
+
runtime: {
|
|
7083
|
+
schemaValues: types_exports.RUNTIME_VALUES,
|
|
7084
|
+
resolve: resolveRuntimePrompt,
|
|
7085
|
+
coverageContexts: [{ backend: "hono" }, { backend: "self" }]
|
|
7086
|
+
},
|
|
7087
|
+
stateManagement: {
|
|
7088
|
+
schemaValues: types_exports.STATE_MANAGEMENT_VALUES,
|
|
7089
|
+
resolve: resolveStateManagementPrompt,
|
|
7090
|
+
coverageContexts: [{ frontends: ["react-vite"] }]
|
|
7091
|
+
},
|
|
7092
|
+
testing: {
|
|
7093
|
+
schemaValues: types_exports.TESTING_VALUES,
|
|
7094
|
+
resolve: ({ value } = {}) => resolveTestingPrompt(value),
|
|
7095
|
+
coverageContexts: [{}]
|
|
7096
|
+
},
|
|
7097
|
+
mobileNavigation: {
|
|
7098
|
+
schemaValues: types_exports.MOBILE_NAVIGATION_VALUES,
|
|
7099
|
+
resolve: ({ value } = {}) => resolveMobileNavigationPrompt(value),
|
|
7100
|
+
coverageContexts: [{}]
|
|
7101
|
+
},
|
|
7102
|
+
mobileUI: {
|
|
7103
|
+
schemaValues: types_exports.MOBILE_UI_VALUES,
|
|
7104
|
+
resolve: ({ value } = {}) => resolveMobileUIPrompt(value),
|
|
7105
|
+
coverageContexts: [{}]
|
|
7106
|
+
},
|
|
7107
|
+
mobileStorage: {
|
|
7108
|
+
schemaValues: types_exports.MOBILE_STORAGE_VALUES,
|
|
7109
|
+
resolve: ({ value } = {}) => resolveMobileStoragePrompt(value),
|
|
7110
|
+
coverageContexts: [{}]
|
|
7111
|
+
},
|
|
7112
|
+
mobileTesting: {
|
|
7113
|
+
schemaValues: types_exports.MOBILE_TESTING_VALUES,
|
|
7114
|
+
resolve: ({ value } = {}) => resolveMobileTestingPrompt(value),
|
|
7115
|
+
coverageContexts: [{}]
|
|
7116
|
+
},
|
|
7117
|
+
mobilePush: {
|
|
7118
|
+
schemaValues: types_exports.MOBILE_PUSH_VALUES,
|
|
7119
|
+
resolve: ({ value } = {}) => resolveMobilePushPrompt(value),
|
|
7120
|
+
coverageContexts: [{}]
|
|
7121
|
+
},
|
|
7122
|
+
mobileOTA: {
|
|
7123
|
+
schemaValues: types_exports.MOBILE_OTA_VALUES,
|
|
7124
|
+
resolve: ({ value } = {}) => resolveMobileOTAPrompt(value),
|
|
7125
|
+
coverageContexts: [{}]
|
|
7126
|
+
},
|
|
7127
|
+
mobileDeepLinking: {
|
|
7128
|
+
schemaValues: types_exports.MOBILE_DEEP_LINKING_VALUES,
|
|
7129
|
+
resolve: ({ value } = {}) => resolveMobileDeepLinkingPrompt(value),
|
|
7130
|
+
coverageContexts: [{}]
|
|
7131
|
+
},
|
|
7132
|
+
uiLibrary: {
|
|
7133
|
+
schemaValues: types_exports.UI_LIBRARY_VALUES,
|
|
7134
|
+
resolve: resolveUILibraryPrompt,
|
|
7135
|
+
coverageContexts: [
|
|
7136
|
+
{ frontends: ["react-vite"] },
|
|
7137
|
+
{ frontends: ["svelte"] },
|
|
7138
|
+
{ frontends: ["solid"] },
|
|
7139
|
+
{ frontends: ["vue"] }
|
|
7140
|
+
]
|
|
7141
|
+
},
|
|
7142
|
+
validation: {
|
|
7143
|
+
schemaValues: types_exports.VALIDATION_VALUES,
|
|
7144
|
+
resolve: ({ value } = {}) => resolveValidationPrompt(value),
|
|
7145
|
+
coverageContexts: [{}]
|
|
7146
|
+
},
|
|
7147
|
+
astroIntegration: {
|
|
7148
|
+
schemaValues: types_exports.ASTRO_INTEGRATION_VALUES,
|
|
7149
|
+
resolve: ({ value } = {}) => resolveAstroIntegrationPrompt(value),
|
|
7150
|
+
coverageContexts: [{}]
|
|
7151
|
+
},
|
|
7152
|
+
rustWebFramework: {
|
|
7153
|
+
schemaValues: types_exports.RUST_WEB_FRAMEWORK_VALUES,
|
|
7154
|
+
resolve: ({ value } = {}) => resolveRustWebFrameworkPrompt(value),
|
|
7155
|
+
coverageContexts: [{}]
|
|
7156
|
+
},
|
|
7157
|
+
rustFrontend: {
|
|
7158
|
+
schemaValues: types_exports.RUST_FRONTEND_VALUES,
|
|
7159
|
+
resolve: ({ value } = {}) => resolveRustFrontendPrompt(value),
|
|
7160
|
+
coverageContexts: [{}]
|
|
7161
|
+
},
|
|
7162
|
+
rustOrm: {
|
|
7163
|
+
schemaValues: types_exports.RUST_ORM_VALUES,
|
|
7164
|
+
resolve: ({ value } = {}) => resolveRustOrmPrompt(value),
|
|
7165
|
+
coverageContexts: [{}]
|
|
7166
|
+
},
|
|
7167
|
+
rustApi: {
|
|
7168
|
+
schemaValues: types_exports.RUST_API_VALUES,
|
|
7169
|
+
resolve: ({ value } = {}) => resolveRustApiPrompt(value),
|
|
7170
|
+
coverageContexts: [{}]
|
|
7171
|
+
},
|
|
7172
|
+
rustCli: {
|
|
7173
|
+
schemaValues: types_exports.RUST_CLI_VALUES,
|
|
7174
|
+
resolve: ({ value } = {}) => resolveRustCliPrompt(value),
|
|
7175
|
+
coverageContexts: [{}]
|
|
7176
|
+
},
|
|
7177
|
+
rustLogging: {
|
|
7178
|
+
schemaValues: types_exports.RUST_LOGGING_VALUES,
|
|
7179
|
+
resolve: ({ value } = {}) => resolveRustLoggingPrompt(value),
|
|
7180
|
+
coverageContexts: [{}]
|
|
7181
|
+
},
|
|
7182
|
+
rustErrorHandling: {
|
|
7183
|
+
schemaValues: types_exports.RUST_ERROR_HANDLING_VALUES,
|
|
7184
|
+
resolve: ({ value } = {}) => resolveRustErrorHandlingPrompt(value),
|
|
7185
|
+
coverageContexts: [{}]
|
|
7186
|
+
},
|
|
7187
|
+
rustLibraries: {
|
|
7188
|
+
schemaValues: types_exports.RUST_LIBRARIES_VALUES,
|
|
7189
|
+
resolve: ({ value } = {}) => resolveRustLibrariesPrompt(value),
|
|
7190
|
+
coverageContexts: [{}, { value: ["none"] }]
|
|
7191
|
+
},
|
|
7192
|
+
rustCaching: {
|
|
7193
|
+
schemaValues: types_exports.RUST_CACHING_VALUES,
|
|
7194
|
+
resolve: ({ value } = {}) => resolveRustCachingPrompt(value),
|
|
7195
|
+
coverageContexts: [{}]
|
|
7196
|
+
},
|
|
7197
|
+
pythonWebFramework: {
|
|
7198
|
+
schemaValues: types_exports.PYTHON_WEB_FRAMEWORK_VALUES,
|
|
7199
|
+
resolve: ({ value } = {}) => resolvePythonWebFrameworkPrompt(value),
|
|
7200
|
+
coverageContexts: [{}]
|
|
7201
|
+
},
|
|
7202
|
+
pythonOrm: {
|
|
7203
|
+
schemaValues: types_exports.PYTHON_ORM_VALUES,
|
|
7204
|
+
resolve: ({ value } = {}) => resolvePythonOrmPrompt(value),
|
|
7205
|
+
coverageContexts: [{}]
|
|
7206
|
+
},
|
|
7207
|
+
pythonValidation: {
|
|
7208
|
+
schemaValues: types_exports.PYTHON_VALIDATION_VALUES,
|
|
7209
|
+
resolve: ({ value } = {}) => resolvePythonValidationPrompt(value),
|
|
7210
|
+
coverageContexts: [{}]
|
|
7211
|
+
},
|
|
7212
|
+
pythonAi: {
|
|
7213
|
+
schemaValues: types_exports.PYTHON_AI_VALUES,
|
|
7214
|
+
resolve: ({ value } = {}) => resolvePythonAiPrompt(value),
|
|
7215
|
+
coverageContexts: [{}, { value: ["none"] }]
|
|
7216
|
+
},
|
|
7217
|
+
pythonAuth: {
|
|
7218
|
+
schemaValues: types_exports.PYTHON_AUTH_VALUES,
|
|
7219
|
+
resolve: ({ value } = {}) => resolvePythonAuthPrompt(value),
|
|
7220
|
+
coverageContexts: [{}]
|
|
7221
|
+
},
|
|
7222
|
+
pythonApi: {
|
|
7223
|
+
schemaValues: types_exports.PYTHON_API_VALUES,
|
|
7224
|
+
resolve: ({ value } = {}) => resolvePythonApiPrompt(value),
|
|
7225
|
+
coverageContexts: [{}]
|
|
7226
|
+
},
|
|
7227
|
+
pythonTaskQueue: {
|
|
7228
|
+
schemaValues: types_exports.PYTHON_TASK_QUEUE_VALUES,
|
|
7229
|
+
resolve: ({ value } = {}) => resolvePythonTaskQueuePrompt(value),
|
|
7230
|
+
coverageContexts: [{}]
|
|
7231
|
+
},
|
|
7232
|
+
pythonGraphql: {
|
|
7233
|
+
schemaValues: types_exports.PYTHON_GRAPHQL_VALUES,
|
|
7234
|
+
resolve: ({ value } = {}) => resolvePythonGraphqlPrompt(value),
|
|
7235
|
+
coverageContexts: [{}]
|
|
7236
|
+
},
|
|
7237
|
+
pythonQuality: {
|
|
7238
|
+
schemaValues: types_exports.PYTHON_QUALITY_VALUES,
|
|
7239
|
+
resolve: ({ value } = {}) => resolvePythonQualityPrompt(value),
|
|
7240
|
+
coverageContexts: [{}]
|
|
7241
|
+
},
|
|
7242
|
+
goWebFramework: {
|
|
7243
|
+
schemaValues: types_exports.GO_WEB_FRAMEWORK_VALUES,
|
|
7244
|
+
resolve: ({ value } = {}) => resolveGoWebFrameworkPrompt(value),
|
|
7245
|
+
coverageContexts: [{}]
|
|
7246
|
+
},
|
|
7247
|
+
goOrm: {
|
|
7248
|
+
schemaValues: types_exports.GO_ORM_VALUES,
|
|
7249
|
+
resolve: ({ value } = {}) => resolveGoOrmPrompt(value),
|
|
7250
|
+
coverageContexts: [{}]
|
|
7251
|
+
},
|
|
7252
|
+
goApi: {
|
|
7253
|
+
schemaValues: types_exports.GO_API_VALUES,
|
|
7254
|
+
resolve: ({ value } = {}) => resolveGoApiPrompt(value),
|
|
7255
|
+
coverageContexts: [{}]
|
|
7256
|
+
},
|
|
7257
|
+
goCli: {
|
|
7258
|
+
schemaValues: types_exports.GO_CLI_VALUES,
|
|
7259
|
+
resolve: ({ value } = {}) => resolveGoCliPrompt(value),
|
|
7260
|
+
coverageContexts: [{}]
|
|
7261
|
+
},
|
|
7262
|
+
goLogging: {
|
|
7263
|
+
schemaValues: types_exports.GO_LOGGING_VALUES,
|
|
7264
|
+
resolve: ({ value } = {}) => resolveGoLoggingPrompt(value),
|
|
7265
|
+
coverageContexts: [{}]
|
|
7266
|
+
},
|
|
7267
|
+
goAuth: {
|
|
7268
|
+
schemaValues: types_exports.GO_AUTH_VALUES,
|
|
7269
|
+
resolve: ({ value } = {}) => resolveGoAuthPrompt(value),
|
|
7270
|
+
coverageContexts: [{}]
|
|
7271
|
+
},
|
|
7272
|
+
javaWebFramework: {
|
|
7273
|
+
schemaValues: types_exports.JAVA_WEB_FRAMEWORK_VALUES,
|
|
7274
|
+
resolve: ({ value } = {}) => resolveJavaWebFrameworkPrompt(value),
|
|
7275
|
+
coverageContexts: [{}]
|
|
7276
|
+
},
|
|
7277
|
+
javaBuildTool: {
|
|
7278
|
+
schemaValues: types_exports.JAVA_BUILD_TOOL_VALUES,
|
|
7279
|
+
resolve: ({ value } = {}) => resolveJavaBuildToolPrompt(value),
|
|
7280
|
+
coverageContexts: [{}]
|
|
7281
|
+
},
|
|
7282
|
+
javaOrm: {
|
|
7283
|
+
schemaValues: types_exports.JAVA_ORM_VALUES,
|
|
7284
|
+
resolve: ({ value } = {}) => resolveJavaOrmPrompt(value),
|
|
7285
|
+
coverageContexts: [{}]
|
|
7286
|
+
},
|
|
7287
|
+
javaAuth: {
|
|
7288
|
+
schemaValues: types_exports.JAVA_AUTH_VALUES,
|
|
7289
|
+
resolve: ({ value } = {}) => resolveJavaAuthPrompt(value),
|
|
7290
|
+
coverageContexts: [{}]
|
|
7291
|
+
},
|
|
7292
|
+
javaLibraries: {
|
|
7293
|
+
schemaValues: types_exports.JAVA_LIBRARIES_VALUES,
|
|
7294
|
+
resolve: ({ value } = {}) => resolveJavaLibrariesPrompt(value),
|
|
7295
|
+
coverageContexts: [{}, { value: ["none"] }]
|
|
7296
|
+
},
|
|
7297
|
+
javaTestingLibraries: {
|
|
7298
|
+
schemaValues: types_exports.JAVA_TESTING_LIBRARIES_VALUES,
|
|
7299
|
+
resolve: ({ value } = {}) => resolveJavaTestingLibrariesPrompt(value),
|
|
7300
|
+
coverageContexts: [{}, { value: ["none"] }]
|
|
7301
|
+
},
|
|
7302
|
+
dotnetWebFramework: {
|
|
7303
|
+
schemaValues: types_exports.DOTNET_WEB_FRAMEWORK_VALUES,
|
|
7304
|
+
resolve: ({ value } = {}) => resolveDotnetWebFrameworkPrompt(value),
|
|
7305
|
+
coverageContexts: [{}]
|
|
7306
|
+
},
|
|
7307
|
+
dotnetOrm: {
|
|
7308
|
+
schemaValues: types_exports.DOTNET_ORM_VALUES,
|
|
7309
|
+
resolve: ({ value } = {}) => resolveDotnetOrmPrompt(value),
|
|
7310
|
+
coverageContexts: [{}]
|
|
7311
|
+
},
|
|
7312
|
+
dotnetAuth: {
|
|
7313
|
+
schemaValues: types_exports.DOTNET_AUTH_VALUES,
|
|
7314
|
+
resolve: ({ value } = {}) => resolveDotnetAuthPrompt(value),
|
|
7315
|
+
coverageContexts: [{}]
|
|
7316
|
+
},
|
|
7317
|
+
dotnetApi: {
|
|
7318
|
+
schemaValues: types_exports.DOTNET_API_VALUES,
|
|
7319
|
+
resolve: ({ value } = {}) => resolveDotnetApiPrompt(value),
|
|
7320
|
+
coverageContexts: [{}]
|
|
7321
|
+
},
|
|
7322
|
+
dotnetTesting: {
|
|
7323
|
+
schemaValues: types_exports.DOTNET_TESTING_VALUES,
|
|
7324
|
+
resolve: ({ value } = {}) => resolveDotnetTestingPrompt(value),
|
|
7325
|
+
coverageContexts: [{}, { value: ["none"] }]
|
|
7326
|
+
},
|
|
7327
|
+
dotnetJobQueue: {
|
|
7328
|
+
schemaValues: types_exports.DOTNET_JOB_QUEUE_VALUES,
|
|
7329
|
+
resolve: ({ value } = {}) => resolveDotnetJobQueuePrompt(value),
|
|
7330
|
+
coverageContexts: [{}]
|
|
7331
|
+
},
|
|
7332
|
+
dotnetRealtime: {
|
|
7333
|
+
schemaValues: types_exports.DOTNET_REALTIME_VALUES,
|
|
7334
|
+
resolve: ({ value } = {}) => resolveDotnetRealtimePrompt(value),
|
|
7335
|
+
coverageContexts: [{}]
|
|
7336
|
+
},
|
|
7337
|
+
dotnetObservability: {
|
|
7338
|
+
schemaValues: types_exports.DOTNET_OBSERVABILITY_VALUES,
|
|
7339
|
+
resolve: ({ value } = {}) => resolveDotnetObservabilityPrompt(value),
|
|
7340
|
+
coverageContexts: [{}, { value: ["none"] }]
|
|
7341
|
+
},
|
|
7342
|
+
dotnetCaching: {
|
|
7343
|
+
schemaValues: types_exports.DOTNET_CACHING_VALUES,
|
|
7344
|
+
resolve: ({ value } = {}) => resolveDotnetCachingPrompt(value),
|
|
7345
|
+
coverageContexts: [{}]
|
|
7346
|
+
},
|
|
7347
|
+
dotnetDeploy: {
|
|
7348
|
+
schemaValues: types_exports.DOTNET_DEPLOY_VALUES,
|
|
7349
|
+
resolve: ({ value } = {}) => resolveDotnetDeployPrompt(value),
|
|
7350
|
+
coverageContexts: [{}]
|
|
7351
|
+
},
|
|
7352
|
+
elixirWebFramework: {
|
|
7353
|
+
schemaValues: types_exports.ELIXIR_WEB_FRAMEWORK_VALUES,
|
|
7354
|
+
resolve: ({ value } = {}) => resolveElixirWebFrameworkPrompt(value),
|
|
7355
|
+
coverageContexts: [{}]
|
|
7356
|
+
},
|
|
7357
|
+
elixirOrm: {
|
|
7358
|
+
schemaValues: types_exports.ELIXIR_ORM_VALUES,
|
|
7359
|
+
resolve: ({ value } = {}) => resolveElixirOrmPrompt(value),
|
|
7360
|
+
coverageContexts: [{}]
|
|
7361
|
+
},
|
|
7362
|
+
elixirAuth: {
|
|
7363
|
+
schemaValues: types_exports.ELIXIR_AUTH_VALUES,
|
|
7364
|
+
resolve: ({ value } = {}) => resolveElixirAuthPrompt(value),
|
|
7365
|
+
coverageContexts: [{}]
|
|
7366
|
+
},
|
|
7367
|
+
elixirApi: {
|
|
7368
|
+
schemaValues: types_exports.ELIXIR_API_VALUES,
|
|
7369
|
+
resolve: ({ value } = {}) => resolveElixirApiPrompt(value),
|
|
7370
|
+
coverageContexts: [{}]
|
|
7371
|
+
},
|
|
7372
|
+
elixirRealtime: {
|
|
7373
|
+
schemaValues: types_exports.ELIXIR_REALTIME_VALUES,
|
|
7374
|
+
resolve: ({ value } = {}) => resolveElixirRealtimePrompt(value),
|
|
7375
|
+
coverageContexts: [{}]
|
|
7376
|
+
},
|
|
7377
|
+
elixirJobs: {
|
|
7378
|
+
schemaValues: types_exports.ELIXIR_JOBS_VALUES,
|
|
7379
|
+
resolve: ({ value } = {}) => resolveElixirJobsPrompt(value),
|
|
7380
|
+
coverageContexts: [{}]
|
|
7381
|
+
},
|
|
7382
|
+
elixirValidation: {
|
|
7383
|
+
schemaValues: types_exports.ELIXIR_VALIDATION_VALUES,
|
|
7384
|
+
resolve: ({ value } = {}) => resolveElixirValidationPrompt(value),
|
|
7385
|
+
coverageContexts: [{}]
|
|
7386
|
+
},
|
|
7387
|
+
elixirHttp: {
|
|
7388
|
+
schemaValues: types_exports.ELIXIR_HTTP_VALUES,
|
|
7389
|
+
resolve: ({ value } = {}) => resolveElixirHttpPrompt(value),
|
|
7390
|
+
coverageContexts: [{}]
|
|
7391
|
+
},
|
|
7392
|
+
elixirJson: {
|
|
7393
|
+
schemaValues: types_exports.ELIXIR_JSON_VALUES,
|
|
7394
|
+
resolve: ({ value } = {}) => resolveElixirJsonPrompt(value),
|
|
7395
|
+
coverageContexts: [{}]
|
|
7396
|
+
},
|
|
7397
|
+
elixirEmail: {
|
|
7398
|
+
schemaValues: types_exports.ELIXIR_EMAIL_VALUES,
|
|
7399
|
+
resolve: ({ value } = {}) => resolveElixirEmailPrompt(value),
|
|
7400
|
+
coverageContexts: [{}]
|
|
7401
|
+
},
|
|
7402
|
+
elixirCaching: {
|
|
7403
|
+
schemaValues: types_exports.ELIXIR_CACHING_VALUES,
|
|
7404
|
+
resolve: ({ value } = {}) => resolveElixirCachingPrompt(value),
|
|
7405
|
+
coverageContexts: [{}]
|
|
7406
|
+
},
|
|
7407
|
+
elixirObservability: {
|
|
7408
|
+
schemaValues: types_exports.ELIXIR_OBSERVABILITY_VALUES,
|
|
7409
|
+
resolve: ({ value } = {}) => resolveElixirObservabilityPrompt(value),
|
|
7410
|
+
coverageContexts: [{}]
|
|
7411
|
+
},
|
|
7412
|
+
elixirTesting: {
|
|
7413
|
+
schemaValues: types_exports.ELIXIR_TESTING_VALUES,
|
|
7414
|
+
resolve: ({ value } = {}) => resolveElixirTestingPrompt(value),
|
|
7415
|
+
coverageContexts: [{}]
|
|
7416
|
+
},
|
|
7417
|
+
elixirQuality: {
|
|
7418
|
+
schemaValues: types_exports.ELIXIR_QUALITY_VALUES,
|
|
7419
|
+
resolve: ({ value } = {}) => resolveElixirQualityPrompt(value),
|
|
7420
|
+
coverageContexts: [{}]
|
|
7421
|
+
},
|
|
7422
|
+
elixirDeploy: {
|
|
7423
|
+
schemaValues: types_exports.ELIXIR_DEPLOY_VALUES,
|
|
7424
|
+
resolve: ({ value } = {}) => resolveElixirDeployPrompt(value),
|
|
7425
|
+
coverageContexts: [{}]
|
|
7426
|
+
}
|
|
7427
|
+
};
|
|
7428
|
+
|
|
7429
|
+
//#endregion
|
|
7430
|
+
//#region src/prompts/search.ts
|
|
7431
|
+
const SEARCH_PROMPT_OPTIONS = [
|
|
7432
|
+
{
|
|
7433
|
+
value: "meilisearch",
|
|
7434
|
+
label: "Meilisearch",
|
|
7435
|
+
hint: "Lightning-fast search engine with typo tolerance"
|
|
7436
|
+
},
|
|
7437
|
+
{
|
|
7438
|
+
value: "typesense",
|
|
7439
|
+
label: "Typesense",
|
|
7440
|
+
hint: "Fast, typo-tolerant search with built-in vector search"
|
|
7441
|
+
},
|
|
7442
|
+
{
|
|
7443
|
+
value: "elasticsearch",
|
|
7444
|
+
label: "Elasticsearch",
|
|
7445
|
+
hint: "Distributed search and analytics engine with local and cloud deployments"
|
|
7446
|
+
},
|
|
7447
|
+
{
|
|
7448
|
+
value: "opensearch",
|
|
7449
|
+
label: "OpenSearch",
|
|
7450
|
+
hint: "Open-source search and analytics suite compatible with Elasticsearch APIs"
|
|
7451
|
+
},
|
|
7452
|
+
{
|
|
7453
|
+
value: "algolia",
|
|
7454
|
+
label: "Algolia",
|
|
7455
|
+
hint: "Hosted search API with instant results, typo tolerance, and analytics"
|
|
7456
|
+
},
|
|
7457
|
+
{
|
|
7458
|
+
value: "none",
|
|
7459
|
+
label: "None",
|
|
7460
|
+
hint: "Skip search engine setup"
|
|
7461
|
+
}
|
|
7462
|
+
];
|
|
7463
|
+
const NON_TYPESCRIPT_SEARCH_PROMPT_OPTIONS = SEARCH_PROMPT_OPTIONS.filter((option) => option.value === "meilisearch" || option.value === "none");
|
|
7464
|
+
const PYTHON_SEARCH_PROMPT_OPTIONS = SEARCH_PROMPT_OPTIONS.filter((option) => option.value === "meilisearch" || option.value === "elasticsearch" || option.value === "none");
|
|
7465
|
+
const GO_SEARCH_PROMPT_OPTIONS = [
|
|
7466
|
+
{
|
|
7467
|
+
value: "meilisearch",
|
|
7468
|
+
label: "Meilisearch",
|
|
7469
|
+
hint: "Lightning-fast search engine with typo tolerance"
|
|
7470
|
+
},
|
|
7471
|
+
{
|
|
7472
|
+
value: "bleve",
|
|
7473
|
+
label: "Bleve",
|
|
7474
|
+
hint: "Embedded, server-less full-text search for Go (no external service)"
|
|
7475
|
+
},
|
|
7476
|
+
{
|
|
7477
|
+
value: "none",
|
|
7478
|
+
label: "None",
|
|
7479
|
+
hint: "Skip search engine setup"
|
|
7480
|
+
}
|
|
7481
|
+
];
|
|
7482
|
+
function resolveSearchPrompt(context = {}) {
|
|
7483
|
+
if (context.ecosystem === "react-native" || context.ecosystem === "elixir") return {
|
|
7484
|
+
shouldPrompt: false,
|
|
7485
|
+
mode: "single",
|
|
7486
|
+
options: [],
|
|
7487
|
+
autoValue: "none"
|
|
7488
|
+
};
|
|
7489
|
+
const options = context.ecosystem === "go" ? GO_SEARCH_PROMPT_OPTIONS : context.ecosystem === "python" ? PYTHON_SEARCH_PROMPT_OPTIONS : context.ecosystem && context.ecosystem !== "typescript" ? NON_TYPESCRIPT_SEARCH_PROMPT_OPTIONS : SEARCH_PROMPT_OPTIONS;
|
|
7490
|
+
if ((!context.ecosystem || context.ecosystem === "typescript") && (context.backend === "none" || context.backend === "convex")) return {
|
|
7491
|
+
shouldPrompt: false,
|
|
7492
|
+
mode: "single",
|
|
7493
|
+
options: [],
|
|
7494
|
+
autoValue: "none"
|
|
7495
|
+
};
|
|
7496
|
+
return context.search !== void 0 ? {
|
|
7497
|
+
shouldPrompt: false,
|
|
7498
|
+
mode: "single",
|
|
7499
|
+
options,
|
|
7500
|
+
autoValue: context.search
|
|
7501
|
+
} : {
|
|
7502
|
+
shouldPrompt: true,
|
|
7503
|
+
mode: "single",
|
|
7504
|
+
options,
|
|
7505
|
+
initialValue: "none"
|
|
7506
|
+
};
|
|
7507
|
+
}
|
|
7508
|
+
async function getSearchChoice(search, backend, ecosystem) {
|
|
7509
|
+
const resolution = resolveSearchPrompt({
|
|
7510
|
+
search,
|
|
7511
|
+
backend,
|
|
7512
|
+
ecosystem
|
|
7513
|
+
});
|
|
7514
|
+
if (!resolution.shouldPrompt) return resolution.autoValue ?? "none";
|
|
7515
|
+
const response = await navigableSelect({
|
|
7516
|
+
message: "Select search engine",
|
|
7517
|
+
options: resolution.options,
|
|
7518
|
+
initialValue: resolution.initialValue
|
|
7519
|
+
});
|
|
7520
|
+
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
7521
|
+
return response;
|
|
7522
|
+
}
|
|
7523
|
+
|
|
7524
|
+
//#endregion
|
|
7525
|
+
//#region src/prompts/vector-db.ts
|
|
7526
|
+
const VECTOR_DB_PROMPT_OPTIONS = [
|
|
7527
|
+
{
|
|
7528
|
+
value: "pgvector",
|
|
7529
|
+
label: "pgvector",
|
|
7530
|
+
hint: "Self-hosted Postgres + pgvector extension for embeddings"
|
|
7531
|
+
},
|
|
7532
|
+
{
|
|
7533
|
+
value: "qdrant",
|
|
7534
|
+
label: "Qdrant",
|
|
7535
|
+
hint: "High-performance open-source vector database"
|
|
7536
|
+
},
|
|
7537
|
+
{
|
|
7538
|
+
value: "chroma",
|
|
7539
|
+
label: "Chroma",
|
|
7540
|
+
hint: "Lightweight open-source embedding database"
|
|
7541
|
+
},
|
|
7542
|
+
{
|
|
7543
|
+
value: "pinecone",
|
|
7544
|
+
label: "Pinecone",
|
|
7545
|
+
hint: "Fully managed serverless vector database"
|
|
7546
|
+
},
|
|
7547
|
+
{
|
|
7548
|
+
value: "none",
|
|
7549
|
+
label: "None",
|
|
7550
|
+
hint: "Skip vector database setup"
|
|
7551
|
+
}
|
|
7552
|
+
];
|
|
7553
|
+
/**
|
|
7554
|
+
* Vector DB is a TypeScript-ecosystem feature backed by a standalone server.
|
|
7555
|
+
* Every provider (including pgvector via a dedicated Postgres instance) is a
|
|
7556
|
+
* separate service, so there is no dependency on the primary database choice.
|
|
7557
|
+
*/
|
|
7558
|
+
function resolveVectorDbPrompt(context = {}) {
|
|
7559
|
+
const skip = () => ({
|
|
7560
|
+
shouldPrompt: false,
|
|
7561
|
+
mode: "single",
|
|
7562
|
+
options: [],
|
|
7563
|
+
autoValue: "none"
|
|
7564
|
+
});
|
|
7565
|
+
if (context.ecosystem && context.ecosystem !== "typescript") return skip();
|
|
7566
|
+
if (context.backend === "none" || context.backend === "convex") return skip();
|
|
7567
|
+
return context.vectorDb !== void 0 ? {
|
|
7568
|
+
shouldPrompt: false,
|
|
7569
|
+
mode: "single",
|
|
7570
|
+
options: VECTOR_DB_PROMPT_OPTIONS,
|
|
7571
|
+
autoValue: context.vectorDb
|
|
7572
|
+
} : {
|
|
7573
|
+
shouldPrompt: true,
|
|
7574
|
+
mode: "single",
|
|
7575
|
+
options: VECTOR_DB_PROMPT_OPTIONS,
|
|
7576
|
+
initialValue: "none"
|
|
7577
|
+
};
|
|
7578
|
+
}
|
|
7579
|
+
async function getVectorDbChoice(vectorDb, backend, ecosystem) {
|
|
7580
|
+
const resolution = resolveVectorDbPrompt({
|
|
7581
|
+
vectorDb,
|
|
7582
|
+
backend,
|
|
7583
|
+
ecosystem
|
|
7584
|
+
});
|
|
7585
|
+
if (!resolution.shouldPrompt) return resolution.autoValue ?? "none";
|
|
7586
|
+
const response = await navigableSelect({
|
|
7587
|
+
message: "Select vector database",
|
|
7588
|
+
options: resolution.options,
|
|
7589
|
+
initialValue: resolution.initialValue
|
|
7590
|
+
});
|
|
7591
|
+
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
7592
|
+
return response;
|
|
7593
|
+
}
|
|
7594
|
+
|
|
7595
|
+
//#endregion
|
|
7596
|
+
//#region src/prompts/server-deploy.ts
|
|
7597
|
+
async function getServerDeploymentChoice(deployment, runtime, backend, _webDeploy) {
|
|
7598
|
+
if (deployment !== void 0) return deployment;
|
|
7599
|
+
if (backend === "none" || backend === "convex") return "none";
|
|
7600
|
+
if (backend !== "hono") return "none";
|
|
7601
|
+
if (runtime === "workers") return "cloudflare";
|
|
7602
|
+
const response = await navigableSelect({
|
|
7603
|
+
message: "Select server deployment",
|
|
7604
|
+
options: getServerDeploymentOptions(runtime),
|
|
7605
|
+
initialValue: DEFAULT_CONFIG.serverDeploy
|
|
7606
|
+
});
|
|
7607
|
+
if (isCancel$1(response)) return exitCancelled("Operation cancelled");
|
|
7608
|
+
return response;
|
|
7609
|
+
}
|
|
7610
|
+
function getServerDeploymentOptions(runtime) {
|
|
7611
|
+
return [
|
|
7612
|
+
{
|
|
7613
|
+
value: "none",
|
|
7614
|
+
label: "None",
|
|
7615
|
+
hint: "Skip server deployment setup"
|
|
7616
|
+
},
|
|
7617
|
+
{
|
|
7618
|
+
value: "railway",
|
|
7619
|
+
label: "Railway",
|
|
7620
|
+
hint: "Deploy with Railway cloud development platform"
|
|
7621
|
+
},
|
|
7622
|
+
{
|
|
7623
|
+
value: "fly",
|
|
7624
|
+
label: "Fly.io",
|
|
7625
|
+
hint: "Deploy globally with Fly.io edge platform"
|
|
7626
|
+
},
|
|
7627
|
+
{
|
|
7628
|
+
value: "render",
|
|
7629
|
+
label: "Render",
|
|
7630
|
+
hint: "Deploy with Render's Blueprint and Docker builds"
|
|
7631
|
+
},
|
|
7632
|
+
...runtime === "node" ? [{
|
|
7633
|
+
value: "netlify",
|
|
7634
|
+
label: "Netlify",
|
|
7635
|
+
hint: "Deploy Hono APIs with Netlify Functions"
|
|
7636
|
+
}] : [],
|
|
7637
|
+
{
|
|
7638
|
+
value: "docker",
|
|
7639
|
+
label: "Docker",
|
|
7640
|
+
hint: "Container-based deployment with Dockerfile"
|
|
7641
|
+
},
|
|
7642
|
+
{
|
|
7643
|
+
value: "sst",
|
|
7644
|
+
label: "SST",
|
|
7645
|
+
hint: "Deploy to AWS with SST (Serverless Stack)"
|
|
7646
|
+
},
|
|
7647
|
+
{
|
|
7648
|
+
value: "vercel",
|
|
7649
|
+
label: "Vercel",
|
|
7650
|
+
hint: "Deploy to Vercel's edge network with zero config"
|
|
7651
|
+
}
|
|
7652
|
+
];
|
|
7653
|
+
}
|
|
7654
|
+
|
|
6703
7655
|
//#endregion
|
|
6704
7656
|
//#region src/prompts/config-prompts.ts
|
|
7657
|
+
const CONFIG_SCOPE_META_KEYS = new Set([
|
|
7658
|
+
"ecosystem",
|
|
7659
|
+
"configScope",
|
|
7660
|
+
"configSections"
|
|
7661
|
+
]);
|
|
7662
|
+
const SHADCN_FLAG_KEYS = new Set([
|
|
7663
|
+
"shadcnBase",
|
|
7664
|
+
"shadcnStyle",
|
|
7665
|
+
"shadcnIconLibrary",
|
|
7666
|
+
"shadcnColorTheme",
|
|
7667
|
+
"shadcnBaseColor",
|
|
7668
|
+
"shadcnFont",
|
|
7669
|
+
"shadcnRadius"
|
|
7670
|
+
]);
|
|
7671
|
+
const CONFIG_PROMPT_ENTRY_KEY_MAP = {
|
|
7672
|
+
ecosystem: true,
|
|
7673
|
+
configScope: true,
|
|
7674
|
+
configSections: true,
|
|
7675
|
+
frontend: true,
|
|
7676
|
+
astroIntegration: true,
|
|
7677
|
+
uiLibrary: true,
|
|
7678
|
+
shadcnOptions: true,
|
|
7679
|
+
cssFramework: true,
|
|
7680
|
+
backend: true,
|
|
7681
|
+
runtime: true,
|
|
7682
|
+
database: true,
|
|
7683
|
+
orm: true,
|
|
7684
|
+
api: true,
|
|
7685
|
+
auth: true,
|
|
7686
|
+
payments: true,
|
|
7687
|
+
email: true,
|
|
7688
|
+
effect: true,
|
|
7689
|
+
addons: true,
|
|
7690
|
+
examples: true,
|
|
7691
|
+
dbSetup: true,
|
|
7692
|
+
webDeploy: true,
|
|
7693
|
+
serverDeploy: true,
|
|
7694
|
+
ai: true,
|
|
7695
|
+
validation: true,
|
|
7696
|
+
forms: true,
|
|
7697
|
+
stateManagement: true,
|
|
7698
|
+
animation: true,
|
|
7699
|
+
testing: true,
|
|
7700
|
+
realtime: true,
|
|
7701
|
+
jobQueue: true,
|
|
7702
|
+
fileUpload: true,
|
|
7703
|
+
logging: true,
|
|
7704
|
+
observability: true,
|
|
7705
|
+
featureFlags: true,
|
|
7706
|
+
analytics: true,
|
|
7707
|
+
cms: true,
|
|
7708
|
+
caching: true,
|
|
7709
|
+
rateLimit: true,
|
|
7710
|
+
i18n: true,
|
|
7711
|
+
search: true,
|
|
7712
|
+
vectorDb: true,
|
|
7713
|
+
fileStorage: true,
|
|
7714
|
+
mobileNavigation: true,
|
|
7715
|
+
mobileUI: true,
|
|
7716
|
+
mobileStorage: true,
|
|
7717
|
+
mobileTesting: true,
|
|
7718
|
+
mobilePush: true,
|
|
7719
|
+
mobileOTA: true,
|
|
7720
|
+
mobileDeepLinking: true,
|
|
7721
|
+
rustWebFramework: true,
|
|
7722
|
+
rustFrontend: true,
|
|
7723
|
+
rustOrm: true,
|
|
7724
|
+
rustApi: true,
|
|
7725
|
+
rustCli: true,
|
|
7726
|
+
rustLibraries: true,
|
|
7727
|
+
rustLogging: true,
|
|
7728
|
+
rustErrorHandling: true,
|
|
7729
|
+
rustCaching: true,
|
|
7730
|
+
rustAuth: true,
|
|
7731
|
+
rustRealtime: true,
|
|
7732
|
+
rustMessageQueue: true,
|
|
7733
|
+
rustObservability: true,
|
|
7734
|
+
rustTemplating: true,
|
|
7735
|
+
pythonWebFramework: true,
|
|
7736
|
+
pythonOrm: true,
|
|
7737
|
+
pythonValidation: true,
|
|
7738
|
+
pythonAi: true,
|
|
7739
|
+
pythonAuth: true,
|
|
7740
|
+
pythonApi: true,
|
|
7741
|
+
pythonTaskQueue: true,
|
|
7742
|
+
pythonGraphql: true,
|
|
7743
|
+
pythonQuality: true,
|
|
7744
|
+
pythonTesting: true,
|
|
7745
|
+
pythonCaching: true,
|
|
7746
|
+
pythonRealtime: true,
|
|
7747
|
+
pythonObservability: true,
|
|
7748
|
+
pythonCli: true,
|
|
7749
|
+
goWebFramework: true,
|
|
7750
|
+
goOrm: true,
|
|
7751
|
+
goApi: true,
|
|
7752
|
+
goCli: true,
|
|
7753
|
+
goLogging: true,
|
|
7754
|
+
goAuth: true,
|
|
7755
|
+
goTesting: true,
|
|
7756
|
+
goRealtime: true,
|
|
7757
|
+
goMessageQueue: true,
|
|
7758
|
+
goCaching: true,
|
|
7759
|
+
goConfig: true,
|
|
7760
|
+
goObservability: true,
|
|
7761
|
+
javaWebFramework: true,
|
|
7762
|
+
javaLanguage: true,
|
|
7763
|
+
javaBuildTool: true,
|
|
7764
|
+
javaOrm: true,
|
|
7765
|
+
javaAuth: true,
|
|
7766
|
+
javaApi: true,
|
|
7767
|
+
javaLogging: true,
|
|
7768
|
+
javaLibraries: true,
|
|
7769
|
+
javaTestingLibraries: true,
|
|
7770
|
+
dotnetWebFramework: true,
|
|
7771
|
+
dotnetOrm: true,
|
|
7772
|
+
dotnetAuth: true,
|
|
7773
|
+
dotnetApi: true,
|
|
7774
|
+
dotnetTesting: true,
|
|
7775
|
+
dotnetJobQueue: true,
|
|
7776
|
+
dotnetRealtime: true,
|
|
7777
|
+
dotnetObservability: true,
|
|
7778
|
+
dotnetValidation: true,
|
|
7779
|
+
dotnetCaching: true,
|
|
7780
|
+
dotnetDeploy: true,
|
|
7781
|
+
elixirWebFramework: true,
|
|
7782
|
+
elixirOrm: true,
|
|
7783
|
+
elixirAuth: true,
|
|
7784
|
+
elixirApi: true,
|
|
7785
|
+
elixirRealtime: true,
|
|
7786
|
+
elixirJobs: true,
|
|
7787
|
+
elixirValidation: true,
|
|
7788
|
+
elixirHttp: true,
|
|
7789
|
+
elixirJson: true,
|
|
7790
|
+
elixirEmail: true,
|
|
7791
|
+
elixirCaching: true,
|
|
7792
|
+
elixirObservability: true,
|
|
7793
|
+
elixirTesting: true,
|
|
7794
|
+
elixirQuality: true,
|
|
7795
|
+
elixirDeploy: true,
|
|
7796
|
+
elixirLibraries: true,
|
|
7797
|
+
aiDocs: true,
|
|
7798
|
+
git: true,
|
|
7799
|
+
workspaceShape: true,
|
|
7800
|
+
packageManager: true,
|
|
7801
|
+
install: true
|
|
7802
|
+
};
|
|
7803
|
+
const CONFIG_PROMPT_ENTRY_KEYS = Object.keys(CONFIG_PROMPT_ENTRY_KEY_MAP);
|
|
7804
|
+
function hasStackPromptFlags(flags) {
|
|
7805
|
+
return Object.keys(flags).some((key) => {
|
|
7806
|
+
if (key === "projectName" || key === "projectDir" || key === "relativePath") return false;
|
|
7807
|
+
if (SHADCN_FLAG_KEYS.has(key)) return true;
|
|
7808
|
+
return CONFIG_PROMPT_ENTRY_KEYS.includes(key);
|
|
7809
|
+
});
|
|
7810
|
+
}
|
|
7811
|
+
function getPromptResolutionValue(key, results, flags) {
|
|
7812
|
+
const resolver = PROMPT_RESOLVER_REGISTRY[key];
|
|
7813
|
+
if (!resolver) return void 0;
|
|
7814
|
+
const frontends = results.frontend ?? flags.frontend;
|
|
7815
|
+
const contextByKey = {
|
|
7816
|
+
frontend: {
|
|
7817
|
+
frontend: flags.frontend,
|
|
7818
|
+
backend: flags.backend,
|
|
7819
|
+
auth: flags.auth
|
|
7820
|
+
},
|
|
7821
|
+
backend: {
|
|
7822
|
+
backendFramework: flags.backend,
|
|
7823
|
+
frontends
|
|
7824
|
+
},
|
|
7825
|
+
runtime: {
|
|
7826
|
+
runtime: flags.runtime,
|
|
7827
|
+
backend: results.backend
|
|
7828
|
+
},
|
|
7829
|
+
database: {
|
|
7830
|
+
database: flags.database,
|
|
7831
|
+
backend: results.backend,
|
|
7832
|
+
runtime: results.runtime
|
|
7833
|
+
},
|
|
7834
|
+
orm: {
|
|
7835
|
+
orm: flags.orm,
|
|
7836
|
+
hasDatabase: results.database !== void 0 && results.database !== "none",
|
|
7837
|
+
database: results.database,
|
|
7838
|
+
backend: results.backend,
|
|
7839
|
+
runtime: results.runtime
|
|
7840
|
+
},
|
|
7841
|
+
api: {
|
|
7842
|
+
api: flags.api,
|
|
7843
|
+
frontend: frontends,
|
|
7844
|
+
backend: results.backend,
|
|
7845
|
+
astroIntegration: results.astroIntegration
|
|
7846
|
+
},
|
|
7847
|
+
auth: {
|
|
7848
|
+
auth: flags.auth,
|
|
7849
|
+
backend: results.backend,
|
|
7850
|
+
frontend: frontends,
|
|
7851
|
+
ecosystem: results.ecosystem
|
|
7852
|
+
},
|
|
7853
|
+
payments: {
|
|
7854
|
+
payments: flags.payments,
|
|
7855
|
+
auth: results.auth,
|
|
7856
|
+
backend: results.backend,
|
|
7857
|
+
frontends
|
|
7858
|
+
},
|
|
7859
|
+
email: {
|
|
7860
|
+
email: flags.email,
|
|
7861
|
+
backend: results.backend,
|
|
7862
|
+
ecosystem: results.ecosystem
|
|
7863
|
+
},
|
|
7864
|
+
uiLibrary: {
|
|
7865
|
+
uiLibrary: flags.uiLibrary,
|
|
7866
|
+
frontends,
|
|
7867
|
+
astroIntegration: results.astroIntegration
|
|
7868
|
+
},
|
|
7869
|
+
cssFramework: {
|
|
7870
|
+
cssFramework: flags.cssFramework,
|
|
7871
|
+
uiLibrary: results.uiLibrary
|
|
7872
|
+
},
|
|
7873
|
+
forms: {
|
|
7874
|
+
forms: flags.forms,
|
|
7875
|
+
frontends
|
|
7876
|
+
},
|
|
7877
|
+
stateManagement: {
|
|
7878
|
+
stateManagement: flags.stateManagement,
|
|
7879
|
+
frontends
|
|
7880
|
+
},
|
|
7881
|
+
animation: {
|
|
7882
|
+
animation: flags.animation,
|
|
7883
|
+
frontends
|
|
7884
|
+
},
|
|
7885
|
+
caching: {
|
|
7886
|
+
caching: flags.caching,
|
|
7887
|
+
backend: results.backend,
|
|
7888
|
+
ecosystem: results.ecosystem
|
|
7889
|
+
},
|
|
7890
|
+
search: {
|
|
7891
|
+
search: flags.search,
|
|
7892
|
+
backend: results.backend,
|
|
7893
|
+
ecosystem: results.ecosystem
|
|
7894
|
+
},
|
|
7895
|
+
observability: {
|
|
7896
|
+
observability: flags.observability,
|
|
7897
|
+
backend: results.backend,
|
|
7898
|
+
ecosystem: results.ecosystem
|
|
7899
|
+
},
|
|
7900
|
+
realtime: {
|
|
7901
|
+
realtime: flags.realtime,
|
|
7902
|
+
backend: results.backend
|
|
7903
|
+
},
|
|
7904
|
+
jobQueue: {
|
|
7905
|
+
jobQueue: flags.jobQueue,
|
|
7906
|
+
backend: results.backend
|
|
7907
|
+
},
|
|
7908
|
+
fileUpload: {
|
|
7909
|
+
fileUpload: flags.fileUpload,
|
|
7910
|
+
backend: results.backend
|
|
7911
|
+
},
|
|
7912
|
+
logging: {
|
|
7913
|
+
logging: flags.logging,
|
|
7914
|
+
backend: results.backend
|
|
7915
|
+
},
|
|
7916
|
+
rateLimit: {
|
|
7917
|
+
rateLimit: flags.rateLimit,
|
|
7918
|
+
backend: results.backend
|
|
7919
|
+
},
|
|
7920
|
+
cms: {
|
|
7921
|
+
cms: flags.cms,
|
|
7922
|
+
backend: results.backend
|
|
7923
|
+
},
|
|
7924
|
+
vectorDb: {
|
|
7925
|
+
vectorDb: flags.vectorDb,
|
|
7926
|
+
backend: results.backend,
|
|
7927
|
+
ecosystem: results.ecosystem
|
|
7928
|
+
},
|
|
7929
|
+
fileStorage: {
|
|
7930
|
+
fileStorage: flags.fileStorage,
|
|
7931
|
+
backend: results.backend
|
|
7932
|
+
}
|
|
7933
|
+
};
|
|
7934
|
+
const selectedValue = flags[key];
|
|
7935
|
+
const context = contextByKey[key] ?? { value: selectedValue };
|
|
7936
|
+
const resolution = resolver.resolve(context);
|
|
7937
|
+
return resolution.autoValue ?? resolution.initialValue;
|
|
7938
|
+
}
|
|
7939
|
+
async function getScopedDefaultPromptValue(key, results, flags) {
|
|
7940
|
+
if (key === "serverDeploy" && results.ecosystem === "typescript") {
|
|
7941
|
+
if (flags.serverDeploy !== void 0) return flags.serverDeploy;
|
|
7942
|
+
if (results.backend !== "hono") return "none";
|
|
7943
|
+
if (results.runtime === "workers") return "cloudflare";
|
|
7944
|
+
return "none";
|
|
7945
|
+
}
|
|
7946
|
+
if (key === "effect" && results.ecosystem === "typescript") return flags.effect ?? (results.backend === "effect" ? "effect-full" : "none");
|
|
7947
|
+
if (key === "validation" && results.ecosystem === "typescript" && results.backend === "effect") return flags.validation ?? "effect-schema";
|
|
7948
|
+
const resolvedValue = getPromptResolutionValue(key, results, flags);
|
|
7949
|
+
if (resolvedValue !== void 0) return resolvedValue;
|
|
7950
|
+
return getDefaultPromptValue(key);
|
|
7951
|
+
}
|
|
7952
|
+
function scopedPrompt(key, flags, prompt) {
|
|
7953
|
+
return (opts) => {
|
|
7954
|
+
if (!CONFIG_SCOPE_META_KEYS.has(key) && !shouldAskConfigPromptKey(opts.results.ecosystem, key, opts.results.configScope, opts.results.configSections)) return getScopedDefaultPromptValue(key, opts.results, flags);
|
|
7955
|
+
return prompt(opts);
|
|
7956
|
+
};
|
|
7957
|
+
}
|
|
6705
7958
|
async function gatherConfig(flags, projectName, projectDir, relativePath) {
|
|
6706
7959
|
if (flags.ecosystem === void 0 && flags.stackParts === void 0) {
|
|
6707
7960
|
if (await getCompositionModeChoice() === "multi") return gatherMultiEcosystemConfig(flags, projectName, projectDir, relativePath);
|
|
6708
7961
|
}
|
|
6709
|
-
const
|
|
7962
|
+
const shouldPromptForScope = !hasStackPromptFlags(flags);
|
|
7963
|
+
const result = await navigableGroup(Object.fromEntries(Object.entries({
|
|
6710
7964
|
ecosystem: () => getEcosystemChoice(flags.ecosystem),
|
|
7965
|
+
configScope: () => shouldPromptForScope ? getConfigScopeChoice() : Promise.resolve("full"),
|
|
7966
|
+
configSections: ({ results }) => {
|
|
7967
|
+
if (!shouldPromptForScope || results.configScope !== "custom") return Promise.resolve([]);
|
|
7968
|
+
return getConfigSectionsChoice(results.ecosystem ?? "typescript");
|
|
7969
|
+
},
|
|
6711
7970
|
frontend: ({ results }) => {
|
|
6712
7971
|
if (results.ecosystem === "react-native") return getNativeFrontendChoice(flags.frontend);
|
|
6713
7972
|
if (results.ecosystem !== "typescript") return Promise.resolve([]);
|
|
@@ -7092,18 +8351,31 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
|
|
|
7092
8351
|
javaLanguage: ({ results }) => {
|
|
7093
8352
|
if (results.ecosystem !== "java") return Promise.resolve("java");
|
|
7094
8353
|
if (results.javaWebFramework !== "spring-boot") return Promise.resolve("java");
|
|
8354
|
+
const kotlinBlocker = (0, types_exports.getKotlinJavaIncompatibilityReason)({
|
|
8355
|
+
javaWebFramework: results.javaWebFramework,
|
|
8356
|
+
javaBuildTool: "maven",
|
|
8357
|
+
email: results.email,
|
|
8358
|
+
search: results.search,
|
|
8359
|
+
caching: results.caching,
|
|
8360
|
+
observability: results.observability
|
|
8361
|
+
});
|
|
8362
|
+
if (kotlinBlocker) {
|
|
8363
|
+
if (flags.javaLanguage === "kotlin") log.warn(`JVM language set to Java: ${kotlinBlocker}`);
|
|
8364
|
+
else if (flags.javaLanguage === void 0 && flags.javaWebFramework === void 0) log.info(`Kotlin not offered: ${kotlinBlocker}`);
|
|
8365
|
+
return Promise.resolve("java");
|
|
8366
|
+
}
|
|
7095
8367
|
if (flags.javaLanguage !== void 0) return getJavaLanguageChoice(flags.javaLanguage);
|
|
7096
8368
|
if (flags.javaWebFramework !== void 0) return Promise.resolve("java");
|
|
7097
8369
|
return getJavaLanguageChoice(flags.javaLanguage);
|
|
7098
8370
|
},
|
|
7099
8371
|
javaBuildTool: ({ results }) => {
|
|
7100
8372
|
if (results.ecosystem !== "java") return Promise.resolve("none");
|
|
7101
|
-
return getJavaBuildToolChoice(flags.javaBuildTool);
|
|
8373
|
+
return getJavaBuildToolChoice(flags.javaBuildTool, results.javaLanguage);
|
|
7102
8374
|
},
|
|
7103
8375
|
javaOrm: ({ results }) => {
|
|
7104
8376
|
if (results.ecosystem !== "java") return Promise.resolve("none");
|
|
7105
8377
|
if (results.javaWebFramework !== "spring-boot" || results.javaBuildTool === "none") return Promise.resolve("none");
|
|
7106
|
-
return getJavaOrmChoice(flags.javaOrm);
|
|
8378
|
+
return getJavaOrmChoice(flags.javaOrm, results.javaLanguage);
|
|
7107
8379
|
},
|
|
7108
8380
|
javaAuth: ({ results }) => {
|
|
7109
8381
|
if (results.ecosystem !== "java") return Promise.resolve("none");
|
|
@@ -7113,7 +8385,7 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
|
|
|
7113
8385
|
javaApi: ({ results }) => {
|
|
7114
8386
|
if (results.ecosystem !== "java") return Promise.resolve("none");
|
|
7115
8387
|
if (results.javaWebFramework !== "spring-boot") return Promise.resolve("none");
|
|
7116
|
-
return getJavaApiChoice(flags.javaApi);
|
|
8388
|
+
return getJavaApiChoice(flags.javaApi, results.javaLanguage);
|
|
7117
8389
|
},
|
|
7118
8390
|
javaLogging: ({ results }) => {
|
|
7119
8391
|
if (results.ecosystem !== "java") return Promise.resolve("none");
|
|
@@ -7123,12 +8395,12 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
|
|
|
7123
8395
|
javaLibraries: ({ results }) => {
|
|
7124
8396
|
if (results.ecosystem !== "java") return Promise.resolve([]);
|
|
7125
8397
|
if (results.javaWebFramework !== "spring-boot" || results.javaBuildTool === "none") return Promise.resolve([]);
|
|
7126
|
-
return getJavaLibrariesChoice(flags.javaLibraries);
|
|
8398
|
+
return getJavaLibrariesChoice(flags.javaLibraries, results.javaLanguage);
|
|
7127
8399
|
},
|
|
7128
8400
|
javaTestingLibraries: ({ results }) => {
|
|
7129
8401
|
if (results.ecosystem !== "java") return Promise.resolve([]);
|
|
7130
8402
|
if (results.javaBuildTool === "none") return Promise.resolve([]);
|
|
7131
|
-
return getJavaTestingLibrariesChoice(flags.javaTestingLibraries);
|
|
8403
|
+
return getJavaTestingLibrariesChoice(flags.javaTestingLibraries, results.javaLanguage);
|
|
7132
8404
|
},
|
|
7133
8405
|
dotnetWebFramework: ({ results }) => {
|
|
7134
8406
|
if (results.ecosystem !== "dotnet") return Promise.resolve("none");
|
|
@@ -7253,7 +8525,7 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
|
|
|
7253
8525
|
return getPackageManagerChoice(flags.packageManager);
|
|
7254
8526
|
},
|
|
7255
8527
|
install: ({ results }) => getinstallChoice(flags.install, results.ecosystem, results.javaBuildTool)
|
|
7256
|
-
}, { onCancel: () => exitCancelled("Operation cancelled") });
|
|
8528
|
+
}).map(([key, prompt]) => [key, scopedPrompt(key, flags, prompt)])), { onCancel: () => exitCancelled("Operation cancelled") });
|
|
7257
8529
|
return {
|
|
7258
8530
|
projectName,
|
|
7259
8531
|
projectDir,
|
|
@@ -7686,6 +8958,17 @@ function displayConfig(config) {
|
|
|
7686
8958
|
return configDisplay.join("\n");
|
|
7687
8959
|
}
|
|
7688
8960
|
|
|
8961
|
+
//#endregion
|
|
8962
|
+
//#region src/utils/open-url.ts
|
|
8963
|
+
async function openUrl(url) {
|
|
8964
|
+
const platform = process.platform;
|
|
8965
|
+
if (platform === "darwin") await $({ stdio: "ignore" })`open ${url}`;
|
|
8966
|
+
else if (platform === "win32") {
|
|
8967
|
+
const escapedUrl = url.replace(/&/g, "^&");
|
|
8968
|
+
await $({ stdio: "ignore" })`cmd /c start "" ${escapedUrl}`;
|
|
8969
|
+
} else await $({ stdio: "ignore" })`xdg-open ${url}`;
|
|
8970
|
+
}
|
|
8971
|
+
|
|
7689
8972
|
//#endregion
|
|
7690
8973
|
//#region src/utils/preflight-display.ts
|
|
7691
8974
|
function displayPreflightWarnings({ warnings }) {
|
|
@@ -9830,11 +11113,10 @@ async function createProject(options, cliInput = {}) {
|
|
|
9830
11113
|
await rollbackPartialProject(projectDir, dirHadContentBefore);
|
|
9831
11114
|
if (error instanceof Error) {
|
|
9832
11115
|
if (!isSilent()) console.error(error.stack);
|
|
9833
|
-
|
|
9834
|
-
} else {
|
|
9835
|
-
if (!isSilent()) console.error(error);
|
|
9836
|
-
exitWithError(`An unexpected error occurred: ${String(error)}`);
|
|
11116
|
+
throw new CLIError(`Error during project creation: ${error.message}`);
|
|
9837
11117
|
}
|
|
11118
|
+
if (!isSilent()) console.error(error);
|
|
11119
|
+
throw new CLIError(`An unexpected error occurred: ${String(error)}`);
|
|
9838
11120
|
}
|
|
9839
11121
|
}
|
|
9840
11122
|
/**
|
|
@@ -9878,6 +11160,70 @@ async function ensurePackageManagerProjectFiles(projectDir, packageManager) {
|
|
|
9878
11160
|
|
|
9879
11161
|
//#endregion
|
|
9880
11162
|
//#region src/helpers/core/command-handlers.ts
|
|
11163
|
+
const NON_STACK_CREATE_OPTION_KEYS = new Set([
|
|
11164
|
+
"template",
|
|
11165
|
+
"fromHistory",
|
|
11166
|
+
"config",
|
|
11167
|
+
"yes",
|
|
11168
|
+
"yolo",
|
|
11169
|
+
"manualDb",
|
|
11170
|
+
"part",
|
|
11171
|
+
"verbose",
|
|
11172
|
+
"dryRun",
|
|
11173
|
+
"verify",
|
|
11174
|
+
"versionChannel",
|
|
11175
|
+
"directoryConflict",
|
|
11176
|
+
"renderTitle",
|
|
11177
|
+
"disableAnalytics"
|
|
11178
|
+
]);
|
|
11179
|
+
const CREATE_STACK_FLAG_KEYS = new Set(Object.keys(CreateCommandOptionsSchema.shape).filter((key) => !NON_STACK_CREATE_OPTION_KEYS.has(key)));
|
|
11180
|
+
function hasCreateStackFlags(input) {
|
|
11181
|
+
return Object.entries(input).some(([key, value]) => {
|
|
11182
|
+
if (value === void 0) return false;
|
|
11183
|
+
if (key === "template" && value === "none") return false;
|
|
11184
|
+
return CREATE_STACK_FLAG_KEYS.has(key);
|
|
11185
|
+
});
|
|
11186
|
+
}
|
|
11187
|
+
function shouldShowBuilderRecommendationPrompt({ input, hasConfigBase, environment = {} }) {
|
|
11188
|
+
if (environment.skipBuilderPrompt === "1") return false;
|
|
11189
|
+
if (!canPromptInteractively({
|
|
11190
|
+
silent: environment.silent,
|
|
11191
|
+
stdinIsTTY: environment.stdinIsTTY,
|
|
11192
|
+
stdoutIsTTY: environment.stdoutIsTTY,
|
|
11193
|
+
ci: environment.ci
|
|
11194
|
+
})) return false;
|
|
11195
|
+
if (input.yes || input.yolo || input.manualDb || input.dryRun || input.part?.length || hasConfigBase || input.config || input.fromHistory || input.template && input.template !== "none") return false;
|
|
11196
|
+
if (hasCreateStackFlags(input)) return false;
|
|
11197
|
+
if (environment.forceBuilderPrompt === "1") return true;
|
|
11198
|
+
return Boolean(environment.npmConfigUserAgent);
|
|
11199
|
+
}
|
|
11200
|
+
async function showBuilderRecommendationPrompt() {
|
|
11201
|
+
note(`The Web Builder walks the full stack visually — every option, live compatibility checks — and hands you back a single command to run.\n\n${BUILDER_URL}`, "Prefer a visual builder?");
|
|
11202
|
+
const response = await navigableSelect({
|
|
11203
|
+
message: "How would you like to continue?",
|
|
11204
|
+
options: [{
|
|
11205
|
+
value: "open",
|
|
11206
|
+
label: "Open the Web Builder",
|
|
11207
|
+
hint: "recommended — opens in your browser"
|
|
11208
|
+
}, {
|
|
11209
|
+
value: "continue",
|
|
11210
|
+
label: "Continue in the CLI"
|
|
11211
|
+
}],
|
|
11212
|
+
initialValue: "open"
|
|
11213
|
+
});
|
|
11214
|
+
if (isCancel$1(response) || isGoBack(response)) return exitCancelled("Operation cancelled");
|
|
11215
|
+
if (response === "open") {
|
|
11216
|
+
try {
|
|
11217
|
+
await openUrl(BUILDER_URL);
|
|
11218
|
+
log.success(pc.blue("Opened Web Builder in your browser."));
|
|
11219
|
+
} catch {
|
|
11220
|
+
log.message(`Please visit ${BUILDER_URL}`);
|
|
11221
|
+
}
|
|
11222
|
+
outro(pc.magenta("Web Builder is ready when you are."));
|
|
11223
|
+
return "opened";
|
|
11224
|
+
}
|
|
11225
|
+
return "continue";
|
|
11226
|
+
}
|
|
9881
11227
|
function getYesBaseConfig(flagConfig) {
|
|
9882
11228
|
const baseConfig = getDefaultConfig();
|
|
9883
11229
|
if (flagConfig.ecosystem !== "react-native") return baseConfig;
|
|
@@ -9929,11 +11275,20 @@ function shouldPromptForVersionChannel(input, hasConfigBase) {
|
|
|
9929
11275
|
if (input.yes || input.part?.length || hasConfigBase || input.versionChannel !== void 0 || isSilent()) return false;
|
|
9930
11276
|
return canPromptInteractively();
|
|
9931
11277
|
}
|
|
11278
|
+
function normalizeKotlinJavaSelection(config) {
|
|
11279
|
+
if (!config.stackParts?.some((part) => part.role === "backend" && part.ecosystem === "java" && !part.ownerPartId && part.source !== "provided") && config.ecosystem !== "java" || config.javaLanguage !== "kotlin") return;
|
|
11280
|
+
const kotlinBlocker = (0, types_exports.getKotlinJavaIncompatibilityReason)(config);
|
|
11281
|
+
if (!kotlinBlocker) return;
|
|
11282
|
+
config.javaLanguage = "java";
|
|
11283
|
+
if (config.stackParts) config.stackParts = config.stackParts.filter((part) => !(part.role === "language" && part.ecosystem === "java" && part.toolId === "kotlin" && part.source !== "provided"));
|
|
11284
|
+
if (!isSilent()) log.warn(pc.yellow(`JVM language set to Java: ${kotlinBlocker}`));
|
|
11285
|
+
}
|
|
9932
11286
|
async function createProjectHandler(input, options = {}) {
|
|
9933
11287
|
const { silent = false } = options;
|
|
9934
11288
|
return runWithContextAsync({ silent }, async () => {
|
|
9935
11289
|
const startTime = Date.now();
|
|
9936
11290
|
const timeScaffolded = (/* @__PURE__ */ new Date()).toISOString();
|
|
11291
|
+
let telemetrySource = silent ? "programmatic" : "cli-interactive";
|
|
9937
11292
|
try {
|
|
9938
11293
|
if (!isSilent() && input.renderTitle !== false) renderTitle();
|
|
9939
11294
|
if (!isSilent()) intro(pc.magenta("Creating a new Better Fullstack project"));
|
|
@@ -9941,6 +11296,17 @@ async function createProjectHandler(input, options = {}) {
|
|
|
9941
11296
|
if (!isSilent() && input.yolo) consola.fatal("YOLO mode enabled - skipping checks. Things may break!");
|
|
9942
11297
|
const configBase = await resolveCreateConfigBase(input);
|
|
9943
11298
|
const hasConfigBase = configBase !== void 0;
|
|
11299
|
+
if (shouldShowBuilderRecommendationPrompt({
|
|
11300
|
+
input,
|
|
11301
|
+
hasConfigBase,
|
|
11302
|
+
environment: {
|
|
11303
|
+
npmConfigUserAgent: process.env.npm_config_user_agent,
|
|
11304
|
+
forceBuilderPrompt: process.env.BFS_FORCE_BUILDER_PROMPT,
|
|
11305
|
+
skipBuilderPrompt: process.env.BFS_SKIP_BUILDER_PROMPT
|
|
11306
|
+
}
|
|
11307
|
+
})) {
|
|
11308
|
+
if (await showBuilderRecommendationPrompt() === "opened") return;
|
|
11309
|
+
}
|
|
9944
11310
|
if (hasConfigBase && !isSilent()) log.info(pc.cyan(input.config ? `Using stack from config file: ${input.config}` : `Using stack from history entry #${input.fromHistory}`));
|
|
9945
11311
|
const useDefaultsForName = Boolean(input.yes) || hasConfigBase;
|
|
9946
11312
|
let currentPathInput;
|
|
@@ -10153,6 +11519,7 @@ async function createProjectHandler(input, options = {}) {
|
|
|
10153
11519
|
const { validatePreflightConfig } = await import("@better-fullstack/template-generator");
|
|
10154
11520
|
let config;
|
|
10155
11521
|
if (cliInput.yes || cliInput.part?.length || hasConfigBase) {
|
|
11522
|
+
if (!silent) telemetrySource = "cli-flags";
|
|
10156
11523
|
const flagConfig = processProvidedFlagsWithoutValidation(cliInput, finalBaseName);
|
|
10157
11524
|
config = {
|
|
10158
11525
|
...getYesBaseConfig(flagConfig),
|
|
@@ -10183,6 +11550,7 @@ async function createProjectHandler(input, options = {}) {
|
|
|
10183
11550
|
};
|
|
10184
11551
|
validateConfigCompatibility(config, providedFlags, cliInput);
|
|
10185
11552
|
}
|
|
11553
|
+
normalizeKotlinJavaSelection(config);
|
|
10186
11554
|
const preflight = validatePreflightConfig(config);
|
|
10187
11555
|
if (preflight.hasWarnings && !isSilent()) displayPreflightWarnings(preflight);
|
|
10188
11556
|
if (input.dryRun) {
|
|
@@ -10232,7 +11600,12 @@ async function createProjectHandler(input, options = {}) {
|
|
|
10232
11600
|
if (cliInput.verify ?? input.verify) await runGeneratedChecks(config);
|
|
10233
11601
|
const reproducibleCommand = generateReproducibleCommand(config);
|
|
10234
11602
|
if (!isSilent()) log.success(pc.blue(`You can reproduce this setup with the following command:\n${reproducibleCommand}`));
|
|
10235
|
-
await trackProjectCreation(config, input.disableAnalytics
|
|
11603
|
+
await trackProjectCreation(config, input.disableAnalytics, {
|
|
11604
|
+
source: telemetrySource,
|
|
11605
|
+
success: true,
|
|
11606
|
+
setupFailures: setupFailures.map((failure) => failure.step),
|
|
11607
|
+
durationMs: Date.now() - startTime
|
|
11608
|
+
});
|
|
10236
11609
|
try {
|
|
10237
11610
|
await addToHistory(config, reproducibleCommand);
|
|
10238
11611
|
} catch (historyError) {
|
|
@@ -10272,6 +11645,12 @@ async function createProjectHandler(input, options = {}) {
|
|
|
10272
11645
|
};
|
|
10273
11646
|
return;
|
|
10274
11647
|
}
|
|
11648
|
+
await trackEvent("project_created", {}, {
|
|
11649
|
+
source: telemetrySource,
|
|
11650
|
+
success: false,
|
|
11651
|
+
errorName: error instanceof Error ? error.name : "UnknownError",
|
|
11652
|
+
durationMs: Date.now() - startTime
|
|
11653
|
+
}, input.disableAnalytics);
|
|
10275
11654
|
if (error instanceof CLIError) {
|
|
10276
11655
|
if (isSilent()) return {
|
|
10277
11656
|
success: false,
|
|
@@ -10326,21 +11705,6 @@ async function handleDirectoryConflictProgrammatically(currentPathInput, strateg
|
|
|
10326
11705
|
}
|
|
10327
11706
|
}
|
|
10328
11707
|
|
|
10329
|
-
//#endregion
|
|
10330
|
-
//#region src/utils/open-url.ts
|
|
10331
|
-
async function openUrl(url) {
|
|
10332
|
-
const platform = process.platform;
|
|
10333
|
-
try {
|
|
10334
|
-
if (platform === "darwin") await $({ stdio: "ignore" })`open ${url}`;
|
|
10335
|
-
else if (platform === "win32") {
|
|
10336
|
-
const escapedUrl = url.replace(/&/g, "^&");
|
|
10337
|
-
await $({ stdio: "ignore" })`cmd /c start "" ${escapedUrl}`;
|
|
10338
|
-
} else await $({ stdio: "ignore" })`xdg-open ${url}`;
|
|
10339
|
-
} catch {
|
|
10340
|
-
log.message(`Please open ${url} in your browser.`);
|
|
10341
|
-
}
|
|
10342
|
-
}
|
|
10343
|
-
|
|
10344
11708
|
//#endregion
|
|
10345
11709
|
//#region src/utils/sponsors.ts
|
|
10346
11710
|
const SPONSORS_JSON_URL = "https://better-fullstack-web.vercel.app/sponsors.json";
|
|
@@ -10439,7 +11803,6 @@ const router = os.router({
|
|
|
10439
11803
|
}
|
|
10440
11804
|
}),
|
|
10441
11805
|
builder: os.meta({ description: "Open the interactive web-based stack builder at better-fullstack.dev" }).handler(async () => {
|
|
10442
|
-
const BUILDER_URL = "https://better-fullstack-web.vercel.app/new";
|
|
10443
11806
|
try {
|
|
10444
11807
|
await openUrl(BUILDER_URL);
|
|
10445
11808
|
log.success(pc.blue("Opened builder in your default browser."));
|
|
@@ -10448,7 +11811,7 @@ const router = os.router({
|
|
|
10448
11811
|
}
|
|
10449
11812
|
}),
|
|
10450
11813
|
add: os.meta({ description: "Add addons, deploy targets, or stack capabilities to an existing Better Fullstack project using its bts.jsonc config" }).input(AddCommandInputSchema).handler(async ({ input }) => {
|
|
10451
|
-
const { addHandler } = await import("./add-handler-
|
|
11814
|
+
const { addHandler } = await import("./add-handler-ztNjzoMN.mjs");
|
|
10452
11815
|
await addHandler(input);
|
|
10453
11816
|
}),
|
|
10454
11817
|
history: os.meta({ description: "Show history of scaffolded projects with reproducible commands" }).input(z.object({
|
|
@@ -10476,7 +11839,7 @@ const router = os.router({
|
|
|
10476
11839
|
ecosystem: z.string().optional().describe("Filter by ecosystem (effect, tanstack, prisma, etc.)"),
|
|
10477
11840
|
"list-ecosystems": z.boolean().default(false).describe("List available ecosystems")
|
|
10478
11841
|
})).handler(async ({ input }) => {
|
|
10479
|
-
const { updateDepsHandler, showEcosystems } = await import("./update-deps-
|
|
11842
|
+
const { updateDepsHandler, showEcosystems } = await import("./update-deps-aD-iQw4U.mjs");
|
|
10480
11843
|
if (input["list-ecosystems"]) {
|
|
10481
11844
|
showEcosystems();
|
|
10482
11845
|
return;
|
|
@@ -10497,7 +11860,7 @@ const router = os.router({
|
|
|
10497
11860
|
})
|
|
10498
11861
|
])).handler(async ({ input }) => {
|
|
10499
11862
|
const [kind, name, options] = input;
|
|
10500
|
-
const { genCommand } = await import("./gen-
|
|
11863
|
+
const { genCommand } = await import("./gen-CCClL7Ve.mjs");
|
|
10501
11864
|
await genCommand({
|
|
10502
11865
|
kind,
|
|
10503
11866
|
name,
|
|
@@ -10515,7 +11878,7 @@ const router = os.router({
|
|
|
10515
11878
|
})
|
|
10516
11879
|
])).handler(async ({ input }) => {
|
|
10517
11880
|
const [action, source, options] = input;
|
|
10518
|
-
const { registryHandler } = await import("./registry-
|
|
11881
|
+
const { registryHandler } = await import("./registry-DSf2CEaU.mjs");
|
|
10519
11882
|
await registryHandler({
|
|
10520
11883
|
action,
|
|
10521
11884
|
source,
|
|
@@ -10532,7 +11895,7 @@ const router = os.router({
|
|
|
10532
11895
|
recordBaseline: z.boolean().optional().default(false).describe("Adopt the current on-disk state as the scaffold baseline (for projects created before the update engine)")
|
|
10533
11896
|
})])).handler(async ({ input }) => {
|
|
10534
11897
|
const [projectDir, options] = input;
|
|
10535
|
-
const { updateCommand } = await import("./update-
|
|
11898
|
+
const { updateCommand } = await import("./update-DJ8CI5KW.mjs");
|
|
10536
11899
|
await updateCommand({
|
|
10537
11900
|
projectDir,
|
|
10538
11901
|
...options
|
|
@@ -10544,7 +11907,7 @@ const router = os.router({
|
|
|
10544
11907
|
}),
|
|
10545
11908
|
doctor: os.meta({ description: "Diagnose a scaffolded Better Fullstack project: verify its bts.jsonc, installed dependencies, required env vars, and run ecosystem build/type checks" }).input(ProjectCheckInputSchema).handler(async ({ input }) => {
|
|
10546
11909
|
const [projectDir, options] = input;
|
|
10547
|
-
const { doctorCommand } = await import("./doctor-
|
|
11910
|
+
const { doctorCommand } = await import("./doctor-a4ca3SMd.mjs");
|
|
10548
11911
|
await doctorCommand({
|
|
10549
11912
|
projectDir,
|
|
10550
11913
|
...options
|
|
@@ -10552,7 +11915,7 @@ const router = os.router({
|
|
|
10552
11915
|
}),
|
|
10553
11916
|
check: os.meta({ description: "Check a scaffolded Better Fullstack project for config, dependency, env, and generated build/type drift" }).input(ProjectCheckInputSchema).handler(async ({ input }) => {
|
|
10554
11917
|
const [projectDir, options] = input;
|
|
10555
|
-
const { doctorCommand } = await import("./doctor-
|
|
11918
|
+
const { doctorCommand } = await import("./doctor-a4ca3SMd.mjs");
|
|
10556
11919
|
await doctorCommand({
|
|
10557
11920
|
projectDir,
|
|
10558
11921
|
...options
|
|
@@ -10563,7 +11926,7 @@ const router = os.router({
|
|
|
10563
11926
|
ecosystem: z.string().optional().describe("Force an ecosystem (typescript, react-native, rust, go, python, java, ...)"),
|
|
10564
11927
|
json: z.boolean().default(false).describe("Output the recommendation as JSON")
|
|
10565
11928
|
})).handler(async ({ input }) => {
|
|
10566
|
-
const { recommendStackFromBrief } = await import("./mcp-
|
|
11929
|
+
const { recommendStackFromBrief } = await import("./mcp-492OkjcS.mjs");
|
|
10567
11930
|
const result = recommendStackFromBrief(input.brief, input.ecosystem);
|
|
10568
11931
|
if (input.json) {
|
|
10569
11932
|
log.message(JSON.stringify(result, null, 2));
|
|
@@ -10638,9 +12001,12 @@ async function docs() {
|
|
|
10638
12001
|
async function builder() {
|
|
10639
12002
|
return caller.builder();
|
|
10640
12003
|
}
|
|
10641
|
-
async function add(input) {
|
|
10642
|
-
const { addHandler } = await import("./add-handler-
|
|
10643
|
-
return addHandler(input, {
|
|
12004
|
+
async function add(input, options) {
|
|
12005
|
+
const { addHandler } = await import("./add-handler-ztNjzoMN.mjs");
|
|
12006
|
+
return addHandler(input, {
|
|
12007
|
+
silent: true,
|
|
12008
|
+
telemetrySource: options?.telemetrySource ?? "programmatic"
|
|
12009
|
+
});
|
|
10644
12010
|
}
|
|
10645
12011
|
async function history(options) {
|
|
10646
12012
|
return caller.history({
|