create-better-fullstack 2.1.6 → 2.1.7
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-D80ZtSO8.mjs → run-D9I7NdES.mjs} +1760 -416
- package/dist/run-buK4aZS8.mjs +15 -0
- 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);
|
|
@@ -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,6 +6015,7 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
|
|
|
5612
6015
|
}
|
|
5613
6016
|
if (backendEcosystem === "java") {
|
|
5614
6017
|
const javaWebFramework = promptValue(await getJavaWebFrameworkChoice(flags.javaWebFramework));
|
|
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));
|
|
5615
6019
|
const javaBuildTool = promptValue(await getJavaBuildToolChoice(flags.javaBuildTool));
|
|
5616
6020
|
if (javaWebFramework !== "none" && javaBuildTool !== "none") {
|
|
5617
6021
|
const databaseConfig = await selectDatabaseConfig(flags);
|
|
@@ -5620,11 +6024,12 @@ async function gatherMultiEcosystemConfig(flags, projectName, projectDir, relati
|
|
|
5620
6024
|
}
|
|
5621
6025
|
const javaOrm = database === "none" || javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? "none" : promptValue(await getJavaOrmChoice(flags.javaOrm));
|
|
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 =
|
|
6027
|
+
const javaLibraries = javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? [] : await scopedPromptValue("java", "javaLibraries", configScope, backendSections, () => getJavaLibrariesChoice(flags.javaLibraries));
|
|
6028
|
+
const javaTestingLibraries = await scopedPromptValue("java", "javaTestingLibraries", configScope, backendSections, () => getJavaTestingLibrariesChoice(flags.javaTestingLibraries));
|
|
5625
6029
|
const javaApi = javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? "none" : promptValue(await getJavaApiChoice(flags.javaApi));
|
|
5626
|
-
const javaLogging = javaWebFramework !== "spring-boot" || javaBuildTool === "none" ? "none" :
|
|
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([]);
|
|
@@ -7253,7 +8512,7 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
|
|
|
7253
8512
|
return getPackageManagerChoice(flags.packageManager);
|
|
7254
8513
|
},
|
|
7255
8514
|
install: ({ results }) => getinstallChoice(flags.install, results.ecosystem, results.javaBuildTool)
|
|
7256
|
-
}, { onCancel: () => exitCancelled("Operation cancelled") });
|
|
8515
|
+
}).map(([key, prompt]) => [key, scopedPrompt(key, flags, prompt)])), { onCancel: () => exitCancelled("Operation cancelled") });
|
|
7257
8516
|
return {
|
|
7258
8517
|
projectName,
|
|
7259
8518
|
projectDir,
|
|
@@ -7789,6 +9048,17 @@ async function setupProjectDirectory(finalPathInput, shouldClearDirectory) {
|
|
|
7789
9048
|
};
|
|
7790
9049
|
}
|
|
7791
9050
|
|
|
9051
|
+
//#endregion
|
|
9052
|
+
//#region src/utils/open-url.ts
|
|
9053
|
+
async function openUrl(url) {
|
|
9054
|
+
const platform = process.platform;
|
|
9055
|
+
if (platform === "darwin") await $({ stdio: "ignore" })`open ${url}`;
|
|
9056
|
+
else if (platform === "win32") {
|
|
9057
|
+
const escapedUrl = url.replace(/&/g, "^&");
|
|
9058
|
+
await $({ stdio: "ignore" })`cmd /c start "" ${escapedUrl}`;
|
|
9059
|
+
} else await $({ stdio: "ignore" })`xdg-open ${url}`;
|
|
9060
|
+
}
|
|
9061
|
+
|
|
7792
9062
|
//#endregion
|
|
7793
9063
|
//#region src/validation.ts
|
|
7794
9064
|
const CORE_STACK_FLAGS = new Set([
|
|
@@ -9830,11 +11100,10 @@ async function createProject(options, cliInput = {}) {
|
|
|
9830
11100
|
await rollbackPartialProject(projectDir, dirHadContentBefore);
|
|
9831
11101
|
if (error instanceof Error) {
|
|
9832
11102
|
if (!isSilent()) console.error(error.stack);
|
|
9833
|
-
|
|
9834
|
-
} else {
|
|
9835
|
-
if (!isSilent()) console.error(error);
|
|
9836
|
-
exitWithError(`An unexpected error occurred: ${String(error)}`);
|
|
11103
|
+
throw new CLIError(`Error during project creation: ${error.message}`);
|
|
9837
11104
|
}
|
|
11105
|
+
if (!isSilent()) console.error(error);
|
|
11106
|
+
throw new CLIError(`An unexpected error occurred: ${String(error)}`);
|
|
9838
11107
|
}
|
|
9839
11108
|
}
|
|
9840
11109
|
/**
|
|
@@ -9878,6 +11147,70 @@ async function ensurePackageManagerProjectFiles(projectDir, packageManager) {
|
|
|
9878
11147
|
|
|
9879
11148
|
//#endregion
|
|
9880
11149
|
//#region src/helpers/core/command-handlers.ts
|
|
11150
|
+
const NON_STACK_CREATE_OPTION_KEYS = new Set([
|
|
11151
|
+
"template",
|
|
11152
|
+
"fromHistory",
|
|
11153
|
+
"config",
|
|
11154
|
+
"yes",
|
|
11155
|
+
"yolo",
|
|
11156
|
+
"manualDb",
|
|
11157
|
+
"part",
|
|
11158
|
+
"verbose",
|
|
11159
|
+
"dryRun",
|
|
11160
|
+
"verify",
|
|
11161
|
+
"versionChannel",
|
|
11162
|
+
"directoryConflict",
|
|
11163
|
+
"renderTitle",
|
|
11164
|
+
"disableAnalytics"
|
|
11165
|
+
]);
|
|
11166
|
+
const CREATE_STACK_FLAG_KEYS = new Set(Object.keys(CreateCommandOptionsSchema.shape).filter((key) => !NON_STACK_CREATE_OPTION_KEYS.has(key)));
|
|
11167
|
+
function hasCreateStackFlags(input) {
|
|
11168
|
+
return Object.entries(input).some(([key, value]) => {
|
|
11169
|
+
if (value === void 0) return false;
|
|
11170
|
+
if (key === "template" && value === "none") return false;
|
|
11171
|
+
return CREATE_STACK_FLAG_KEYS.has(key);
|
|
11172
|
+
});
|
|
11173
|
+
}
|
|
11174
|
+
function shouldShowBuilderRecommendationPrompt({ input, hasConfigBase, environment = {} }) {
|
|
11175
|
+
if (environment.skipBuilderPrompt === "1") return false;
|
|
11176
|
+
if (!canPromptInteractively({
|
|
11177
|
+
silent: environment.silent,
|
|
11178
|
+
stdinIsTTY: environment.stdinIsTTY,
|
|
11179
|
+
stdoutIsTTY: environment.stdoutIsTTY,
|
|
11180
|
+
ci: environment.ci
|
|
11181
|
+
})) return false;
|
|
11182
|
+
if (input.yes || input.yolo || input.manualDb || input.dryRun || input.part?.length || hasConfigBase || input.config || input.fromHistory || input.template && input.template !== "none") return false;
|
|
11183
|
+
if (hasCreateStackFlags(input)) return false;
|
|
11184
|
+
if (environment.forceBuilderPrompt === "1") return true;
|
|
11185
|
+
return Boolean(environment.npmConfigUserAgent);
|
|
11186
|
+
}
|
|
11187
|
+
async function showBuilderRecommendationPrompt() {
|
|
11188
|
+
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?");
|
|
11189
|
+
const response = await navigableSelect({
|
|
11190
|
+
message: "How would you like to continue?",
|
|
11191
|
+
options: [{
|
|
11192
|
+
value: "open",
|
|
11193
|
+
label: "Open the Web Builder",
|
|
11194
|
+
hint: "recommended — opens in your browser"
|
|
11195
|
+
}, {
|
|
11196
|
+
value: "continue",
|
|
11197
|
+
label: "Continue in the CLI"
|
|
11198
|
+
}],
|
|
11199
|
+
initialValue: "open"
|
|
11200
|
+
});
|
|
11201
|
+
if (isCancel$1(response) || isGoBack(response)) return exitCancelled("Operation cancelled");
|
|
11202
|
+
if (response === "open") {
|
|
11203
|
+
try {
|
|
11204
|
+
await openUrl(BUILDER_URL);
|
|
11205
|
+
log.success(pc.blue("Opened Web Builder in your browser."));
|
|
11206
|
+
} catch {
|
|
11207
|
+
log.message(`Please visit ${BUILDER_URL}`);
|
|
11208
|
+
}
|
|
11209
|
+
outro(pc.magenta("Web Builder is ready when you are."));
|
|
11210
|
+
return "opened";
|
|
11211
|
+
}
|
|
11212
|
+
return "continue";
|
|
11213
|
+
}
|
|
9881
11214
|
function getYesBaseConfig(flagConfig) {
|
|
9882
11215
|
const baseConfig = getDefaultConfig();
|
|
9883
11216
|
if (flagConfig.ecosystem !== "react-native") return baseConfig;
|
|
@@ -9934,6 +11267,7 @@ async function createProjectHandler(input, options = {}) {
|
|
|
9934
11267
|
return runWithContextAsync({ silent }, async () => {
|
|
9935
11268
|
const startTime = Date.now();
|
|
9936
11269
|
const timeScaffolded = (/* @__PURE__ */ new Date()).toISOString();
|
|
11270
|
+
let telemetrySource = silent ? "programmatic" : "cli-interactive";
|
|
9937
11271
|
try {
|
|
9938
11272
|
if (!isSilent() && input.renderTitle !== false) renderTitle();
|
|
9939
11273
|
if (!isSilent()) intro(pc.magenta("Creating a new Better Fullstack project"));
|
|
@@ -9941,6 +11275,17 @@ async function createProjectHandler(input, options = {}) {
|
|
|
9941
11275
|
if (!isSilent() && input.yolo) consola.fatal("YOLO mode enabled - skipping checks. Things may break!");
|
|
9942
11276
|
const configBase = await resolveCreateConfigBase(input);
|
|
9943
11277
|
const hasConfigBase = configBase !== void 0;
|
|
11278
|
+
if (shouldShowBuilderRecommendationPrompt({
|
|
11279
|
+
input,
|
|
11280
|
+
hasConfigBase,
|
|
11281
|
+
environment: {
|
|
11282
|
+
npmConfigUserAgent: process.env.npm_config_user_agent,
|
|
11283
|
+
forceBuilderPrompt: process.env.BFS_FORCE_BUILDER_PROMPT,
|
|
11284
|
+
skipBuilderPrompt: process.env.BFS_SKIP_BUILDER_PROMPT
|
|
11285
|
+
}
|
|
11286
|
+
})) {
|
|
11287
|
+
if (await showBuilderRecommendationPrompt() === "opened") return;
|
|
11288
|
+
}
|
|
9944
11289
|
if (hasConfigBase && !isSilent()) log.info(pc.cyan(input.config ? `Using stack from config file: ${input.config}` : `Using stack from history entry #${input.fromHistory}`));
|
|
9945
11290
|
const useDefaultsForName = Boolean(input.yes) || hasConfigBase;
|
|
9946
11291
|
let currentPathInput;
|
|
@@ -10153,6 +11498,7 @@ async function createProjectHandler(input, options = {}) {
|
|
|
10153
11498
|
const { validatePreflightConfig } = await import("@better-fullstack/template-generator");
|
|
10154
11499
|
let config;
|
|
10155
11500
|
if (cliInput.yes || cliInput.part?.length || hasConfigBase) {
|
|
11501
|
+
if (!silent) telemetrySource = "cli-flags";
|
|
10156
11502
|
const flagConfig = processProvidedFlagsWithoutValidation(cliInput, finalBaseName);
|
|
10157
11503
|
config = {
|
|
10158
11504
|
...getYesBaseConfig(flagConfig),
|
|
@@ -10232,7 +11578,12 @@ async function createProjectHandler(input, options = {}) {
|
|
|
10232
11578
|
if (cliInput.verify ?? input.verify) await runGeneratedChecks(config);
|
|
10233
11579
|
const reproducibleCommand = generateReproducibleCommand(config);
|
|
10234
11580
|
if (!isSilent()) log.success(pc.blue(`You can reproduce this setup with the following command:\n${reproducibleCommand}`));
|
|
10235
|
-
await trackProjectCreation(config, input.disableAnalytics
|
|
11581
|
+
await trackProjectCreation(config, input.disableAnalytics, {
|
|
11582
|
+
source: telemetrySource,
|
|
11583
|
+
success: true,
|
|
11584
|
+
setupFailures: setupFailures.map((failure) => failure.step),
|
|
11585
|
+
durationMs: Date.now() - startTime
|
|
11586
|
+
});
|
|
10236
11587
|
try {
|
|
10237
11588
|
await addToHistory(config, reproducibleCommand);
|
|
10238
11589
|
} catch (historyError) {
|
|
@@ -10272,6 +11623,12 @@ async function createProjectHandler(input, options = {}) {
|
|
|
10272
11623
|
};
|
|
10273
11624
|
return;
|
|
10274
11625
|
}
|
|
11626
|
+
await trackEvent("project_created", {}, {
|
|
11627
|
+
source: telemetrySource,
|
|
11628
|
+
success: false,
|
|
11629
|
+
errorName: error instanceof Error ? error.name : "UnknownError",
|
|
11630
|
+
durationMs: Date.now() - startTime
|
|
11631
|
+
}, input.disableAnalytics);
|
|
10275
11632
|
if (error instanceof CLIError) {
|
|
10276
11633
|
if (isSilent()) return {
|
|
10277
11634
|
success: false,
|
|
@@ -10326,21 +11683,6 @@ async function handleDirectoryConflictProgrammatically(currentPathInput, strateg
|
|
|
10326
11683
|
}
|
|
10327
11684
|
}
|
|
10328
11685
|
|
|
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
11686
|
//#endregion
|
|
10345
11687
|
//#region src/utils/sponsors.ts
|
|
10346
11688
|
const SPONSORS_JSON_URL = "https://better-fullstack-web.vercel.app/sponsors.json";
|
|
@@ -10439,7 +11781,6 @@ const router = os.router({
|
|
|
10439
11781
|
}
|
|
10440
11782
|
}),
|
|
10441
11783
|
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
11784
|
try {
|
|
10444
11785
|
await openUrl(BUILDER_URL);
|
|
10445
11786
|
log.success(pc.blue("Opened builder in your default browser."));
|
|
@@ -10448,7 +11789,7 @@ const router = os.router({
|
|
|
10448
11789
|
}
|
|
10449
11790
|
}),
|
|
10450
11791
|
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-
|
|
11792
|
+
const { addHandler } = await import("./add-handler-ztNjzoMN.mjs");
|
|
10452
11793
|
await addHandler(input);
|
|
10453
11794
|
}),
|
|
10454
11795
|
history: os.meta({ description: "Show history of scaffolded projects with reproducible commands" }).input(z.object({
|
|
@@ -10476,7 +11817,7 @@ const router = os.router({
|
|
|
10476
11817
|
ecosystem: z.string().optional().describe("Filter by ecosystem (effect, tanstack, prisma, etc.)"),
|
|
10477
11818
|
"list-ecosystems": z.boolean().default(false).describe("List available ecosystems")
|
|
10478
11819
|
})).handler(async ({ input }) => {
|
|
10479
|
-
const { updateDepsHandler, showEcosystems } = await import("./update-deps-
|
|
11820
|
+
const { updateDepsHandler, showEcosystems } = await import("./update-deps-aD-iQw4U.mjs");
|
|
10480
11821
|
if (input["list-ecosystems"]) {
|
|
10481
11822
|
showEcosystems();
|
|
10482
11823
|
return;
|
|
@@ -10497,7 +11838,7 @@ const router = os.router({
|
|
|
10497
11838
|
})
|
|
10498
11839
|
])).handler(async ({ input }) => {
|
|
10499
11840
|
const [kind, name, options] = input;
|
|
10500
|
-
const { genCommand } = await import("./gen-
|
|
11841
|
+
const { genCommand } = await import("./gen-CCClL7Ve.mjs");
|
|
10501
11842
|
await genCommand({
|
|
10502
11843
|
kind,
|
|
10503
11844
|
name,
|
|
@@ -10515,7 +11856,7 @@ const router = os.router({
|
|
|
10515
11856
|
})
|
|
10516
11857
|
])).handler(async ({ input }) => {
|
|
10517
11858
|
const [action, source, options] = input;
|
|
10518
|
-
const { registryHandler } = await import("./registry-
|
|
11859
|
+
const { registryHandler } = await import("./registry-DSf2CEaU.mjs");
|
|
10519
11860
|
await registryHandler({
|
|
10520
11861
|
action,
|
|
10521
11862
|
source,
|
|
@@ -10532,7 +11873,7 @@ const router = os.router({
|
|
|
10532
11873
|
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
11874
|
})])).handler(async ({ input }) => {
|
|
10534
11875
|
const [projectDir, options] = input;
|
|
10535
|
-
const { updateCommand } = await import("./update-
|
|
11876
|
+
const { updateCommand } = await import("./update-DJ8CI5KW.mjs");
|
|
10536
11877
|
await updateCommand({
|
|
10537
11878
|
projectDir,
|
|
10538
11879
|
...options
|
|
@@ -10544,7 +11885,7 @@ const router = os.router({
|
|
|
10544
11885
|
}),
|
|
10545
11886
|
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
11887
|
const [projectDir, options] = input;
|
|
10547
|
-
const { doctorCommand } = await import("./doctor-
|
|
11888
|
+
const { doctorCommand } = await import("./doctor-a4ca3SMd.mjs");
|
|
10548
11889
|
await doctorCommand({
|
|
10549
11890
|
projectDir,
|
|
10550
11891
|
...options
|
|
@@ -10552,7 +11893,7 @@ const router = os.router({
|
|
|
10552
11893
|
}),
|
|
10553
11894
|
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
11895
|
const [projectDir, options] = input;
|
|
10555
|
-
const { doctorCommand } = await import("./doctor-
|
|
11896
|
+
const { doctorCommand } = await import("./doctor-a4ca3SMd.mjs");
|
|
10556
11897
|
await doctorCommand({
|
|
10557
11898
|
projectDir,
|
|
10558
11899
|
...options
|
|
@@ -10563,7 +11904,7 @@ const router = os.router({
|
|
|
10563
11904
|
ecosystem: z.string().optional().describe("Force an ecosystem (typescript, react-native, rust, go, python, java, ...)"),
|
|
10564
11905
|
json: z.boolean().default(false).describe("Output the recommendation as JSON")
|
|
10565
11906
|
})).handler(async ({ input }) => {
|
|
10566
|
-
const { recommendStackFromBrief } = await import("./mcp-
|
|
11907
|
+
const { recommendStackFromBrief } = await import("./mcp-492OkjcS.mjs");
|
|
10567
11908
|
const result = recommendStackFromBrief(input.brief, input.ecosystem);
|
|
10568
11909
|
if (input.json) {
|
|
10569
11910
|
log.message(JSON.stringify(result, null, 2));
|
|
@@ -10638,9 +11979,12 @@ async function docs() {
|
|
|
10638
11979
|
async function builder() {
|
|
10639
11980
|
return caller.builder();
|
|
10640
11981
|
}
|
|
10641
|
-
async function add(input) {
|
|
10642
|
-
const { addHandler } = await import("./add-handler-
|
|
10643
|
-
return addHandler(input, {
|
|
11982
|
+
async function add(input, options) {
|
|
11983
|
+
const { addHandler } = await import("./add-handler-ztNjzoMN.mjs");
|
|
11984
|
+
return addHandler(input, {
|
|
11985
|
+
silent: true,
|
|
11986
|
+
telemetrySource: options?.telemetrySource ?? "programmatic"
|
|
11987
|
+
});
|
|
10644
11988
|
}
|
|
10645
11989
|
async function history(options) {
|
|
10646
11990
|
return caller.history({
|