@donotdev/cli 0.0.15 → 0.0.17
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/dependencies-matrix.json +67 -147
- package/dist/bin/commands/build.js +69 -52
- package/dist/bin/commands/bump.js +15 -14
- package/dist/bin/commands/create-app.js +258 -55
- package/dist/bin/commands/create-project.js +290 -161
- package/dist/bin/commands/deploy.js +146 -63
- package/dist/bin/commands/dev.js +43 -24
- package/dist/bin/commands/doctor.d.ts +6 -0
- package/dist/bin/commands/doctor.d.ts.map +1 -0
- package/dist/bin/commands/{lint.js → doctor.js} +1370 -146
- package/dist/bin/commands/doctor.js.map +1 -0
- package/dist/bin/commands/emu.js +295 -107
- package/dist/bin/commands/make-admin.js +77519 -11
- package/dist/bin/commands/preview.js +44 -25
- package/dist/bin/commands/setup.d.ts +6 -0
- package/dist/bin/commands/setup.d.ts.map +1 -0
- package/dist/bin/commands/setup.js +12123 -0
- package/dist/bin/commands/setup.js.map +1 -0
- package/dist/bin/commands/type-check.d.ts.map +1 -1
- package/dist/bin/commands/type-check.js +2022 -283
- package/dist/bin/commands/type-check.js.map +1 -1
- package/dist/bin/dndev.js +54 -58
- package/dist/bin/donotdev.js +54 -58
- package/dist/index.js +860 -459
- package/package.json +2 -2
- package/templates/app-expo/.env.example +2 -22
- package/templates/app-expo/README.md.example +1 -1
- package/templates/app-expo/assets/adaptive-icon.png +0 -0
- package/templates/app-expo/assets/favicon.png +0 -0
- package/templates/app-expo/assets/icon.png +0 -0
- package/templates/app-expo/assets/splash.png +0 -0
- package/templates/app-expo/src/config/app.ts.example +46 -0
- package/templates/app-expo/src/config/providers.ts.example +7 -0
- package/templates/app-next/src/config/providers.ts.example +7 -0
- package/templates/app-vite/src/config/providers.ts.example +7 -0
- package/templates/app-vite/src/pages/HomePage.tsx.example +1 -1
- package/templates/functions-firebase/README.md.example +1 -1
- package/templates/functions-firebase/functions-firebase/.env.example.example +1 -1
- package/templates/functions-firebase/functions-firebase/README.md.example +1 -1
- package/templates/functions-firebase/functions-firebase/tsconfig.json.example +1 -1
- package/templates/functions-firebase/functions.config.js.example +1 -1
- package/templates/functions-supabase/supabase/config.toml.example +59 -0
- package/templates/functions-supabase/supabase/functions/.env.example +13 -0
- package/templates/functions-supabase/supabase/functions/deno.json.example +8 -0
- package/templates/overlay-firebase/env.fragment.example +1 -1
- package/templates/overlay-firebase/env.fragment.expo.example +1 -1
- package/templates/overlay-firebase/env.fragment.nextjs.example +1 -1
- package/templates/overlay-supabase/env.fragment.example +8 -3
- package/templates/overlay-supabase/env.fragment.expo.example +8 -3
- package/templates/overlay-supabase/env.fragment.nextjs.example +8 -3
- package/templates/overlay-vercel/env.fragment.example +1 -1
- package/templates/overlay-vercel/env.fragment.nextjs.example +1 -1
- package/templates/root-consumer/AI.md.example +15 -0
- package/templates/root-consumer/guides/dndev/AGENT_START_HERE.md.example +2 -2
- package/templates/root-consumer/guides/dndev/ENV_SETUP.md.example +12 -12
- package/templates/root-consumer/guides/dndev/INDEX.md.example +3 -3
- package/templates/root-consumer/guides/dndev/SETUP_APP_CONFIG.md.example +3 -3
- package/templates/root-consumer/guides/dndev/SETUP_AUTH.md.example +13 -6
- package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +149 -988
- package/templates/root-consumer/guides/dndev/SETUP_FIREBASE.md.example +72 -20
- package/templates/root-consumer/guides/dndev/SETUP_FUNCTIONS.md.example +6 -111
- package/templates/root-consumer/guides/dndev/SETUP_OAUTH_PROVIDERS.md.example +60 -0
- package/templates/root-consumer/guides/dndev/SETUP_STRIPE.md.example +62 -0
- package/templates/root-consumer/guides/dndev/SETUP_SUPABASE.md.example +124 -33
- package/templates/root-consumer/guides/dndev/SETUP_VERCEL.md.example +108 -91
- package/templates/root-consumer/guides/dndev/advanced/EMULATORS.md.example +2 -2
- package/templates/root-consumer/guides/wai-way/WAI_WAY_CLI.md.example +7 -8
- package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +9 -5
- package/dist/bin/commands/firebase-setup.d.ts +0 -6
- package/dist/bin/commands/firebase-setup.d.ts.map +0 -1
- package/dist/bin/commands/firebase-setup.js +0 -7
- package/dist/bin/commands/firebase-setup.js.map +0 -1
- package/dist/bin/commands/lint.d.ts +0 -11
- package/dist/bin/commands/lint.d.ts.map +0 -1
- package/dist/bin/commands/lint.js.map +0 -1
- package/dist/bin/commands/staging.d.ts +0 -11
- package/dist/bin/commands/staging.d.ts.map +0 -1
- package/dist/bin/commands/staging.js +0 -12
- package/dist/bin/commands/staging.js.map +0 -1
- package/dist/bin/commands/supabase-setup.d.ts +0 -6
- package/dist/bin/commands/supabase-setup.d.ts.map +0 -1
- package/dist/bin/commands/supabase-setup.js +0 -7
- package/dist/bin/commands/supabase-setup.js.map +0 -1
|
@@ -8713,15 +8713,14 @@ function getMatrixPath(mode) {
|
|
|
8713
8713
|
}
|
|
8714
8714
|
const executionMode = mode || detectExecutionMode();
|
|
8715
8715
|
if (executionMode === "development") {
|
|
8716
|
-
const
|
|
8717
|
-
|
|
8718
|
-
|
|
8719
|
-
|
|
8720
|
-
|
|
8721
|
-
|
|
8722
|
-
|
|
8723
|
-
|
|
8724
|
-
}
|
|
8716
|
+
const templatesRoot = getTemplatesRoot();
|
|
8717
|
+
const devPath = normalizePath(
|
|
8718
|
+
templatesRoot,
|
|
8719
|
+
"..",
|
|
8720
|
+
"dependencies-matrix.json"
|
|
8721
|
+
);
|
|
8722
|
+
if (pathExists(devPath)) {
|
|
8723
|
+
return devPath;
|
|
8725
8724
|
}
|
|
8726
8725
|
}
|
|
8727
8726
|
return null;
|
|
@@ -8736,8 +8735,8 @@ function getCliVersion(mode) {
|
|
|
8736
8735
|
}
|
|
8737
8736
|
const executionMode = mode || detectExecutionMode();
|
|
8738
8737
|
if (executionMode === "development") {
|
|
8739
|
-
const
|
|
8740
|
-
const cliPackageJson =
|
|
8738
|
+
const templatesRoot = getTemplatesRoot();
|
|
8739
|
+
const cliPackageJson = normalizePath(templatesRoot, "..", "package.json");
|
|
8741
8740
|
if (pathExists(cliPackageJson)) {
|
|
8742
8741
|
const pkg = readSync(cliPackageJson, { format: "json" });
|
|
8743
8742
|
return String(pkg?.version || "0.0.0");
|
|
@@ -9026,7 +9025,7 @@ function generatePackageJson(templateName, mode, options = {}) {
|
|
|
9026
9025
|
}
|
|
9027
9026
|
if (templateName.includes("functions")) {
|
|
9028
9027
|
result.main = "lib/index.js";
|
|
9029
|
-
result.engines = { node: "
|
|
9028
|
+
result.engines = { node: "22" };
|
|
9030
9029
|
if (options.appName) {
|
|
9031
9030
|
const platform = templateName.includes("vercel") ? "Vercel" : "Firebase";
|
|
9032
9031
|
result.description = `${options.appName} ${platform} Functions`;
|
|
@@ -9071,18 +9070,102 @@ init_pathResolver();
|
|
|
9071
9070
|
// packages/tooling/src/scaffolding/scaffold-matrix.ts
|
|
9072
9071
|
init_utils();
|
|
9073
9072
|
var MATRIX = [
|
|
9074
|
-
{
|
|
9075
|
-
|
|
9076
|
-
|
|
9077
|
-
|
|
9078
|
-
|
|
9079
|
-
|
|
9080
|
-
|
|
9081
|
-
|
|
9082
|
-
{
|
|
9083
|
-
|
|
9084
|
-
|
|
9085
|
-
|
|
9073
|
+
{
|
|
9074
|
+
builder: "vite",
|
|
9075
|
+
backend: "none",
|
|
9076
|
+
baseTemplate: "app-vite",
|
|
9077
|
+
overlay: null,
|
|
9078
|
+
deployConfig: null,
|
|
9079
|
+
functionsTemplate: null
|
|
9080
|
+
},
|
|
9081
|
+
{
|
|
9082
|
+
builder: "vite",
|
|
9083
|
+
backend: "firebase",
|
|
9084
|
+
baseTemplate: "app-vite",
|
|
9085
|
+
overlay: "overlay-firebase",
|
|
9086
|
+
deployConfig: "firebase",
|
|
9087
|
+
functionsTemplate: "functions-firebase"
|
|
9088
|
+
},
|
|
9089
|
+
{
|
|
9090
|
+
builder: "vite",
|
|
9091
|
+
backend: "supabase",
|
|
9092
|
+
baseTemplate: "app-vite",
|
|
9093
|
+
overlay: "overlay-supabase",
|
|
9094
|
+
deployConfig: "vercel-supabase",
|
|
9095
|
+
functionsTemplate: "functions-supabase"
|
|
9096
|
+
},
|
|
9097
|
+
{
|
|
9098
|
+
builder: "vite",
|
|
9099
|
+
backend: "vercel",
|
|
9100
|
+
baseTemplate: "app-vite",
|
|
9101
|
+
overlay: "overlay-vercel",
|
|
9102
|
+
deployConfig: "vercel-vercel",
|
|
9103
|
+
functionsTemplate: "functions-vercel"
|
|
9104
|
+
},
|
|
9105
|
+
{
|
|
9106
|
+
builder: "nextjs",
|
|
9107
|
+
backend: "none",
|
|
9108
|
+
baseTemplate: "app-next",
|
|
9109
|
+
overlay: null,
|
|
9110
|
+
deployConfig: null,
|
|
9111
|
+
functionsTemplate: null
|
|
9112
|
+
},
|
|
9113
|
+
{
|
|
9114
|
+
builder: "nextjs",
|
|
9115
|
+
backend: "firebase",
|
|
9116
|
+
baseTemplate: "app-next",
|
|
9117
|
+
overlay: "overlay-firebase",
|
|
9118
|
+
deployConfig: "firebase",
|
|
9119
|
+
functionsTemplate: "functions-firebase"
|
|
9120
|
+
},
|
|
9121
|
+
{
|
|
9122
|
+
builder: "nextjs",
|
|
9123
|
+
backend: "supabase",
|
|
9124
|
+
baseTemplate: "app-next",
|
|
9125
|
+
overlay: "overlay-supabase",
|
|
9126
|
+
deployConfig: "vercel-supabase",
|
|
9127
|
+
functionsTemplate: "functions-supabase"
|
|
9128
|
+
},
|
|
9129
|
+
{
|
|
9130
|
+
builder: "nextjs",
|
|
9131
|
+
backend: "vercel",
|
|
9132
|
+
baseTemplate: "app-next",
|
|
9133
|
+
overlay: "overlay-vercel",
|
|
9134
|
+
deployConfig: "vercel-vercel",
|
|
9135
|
+
functionsTemplate: "functions-vercel"
|
|
9136
|
+
},
|
|
9137
|
+
{
|
|
9138
|
+
builder: "expo",
|
|
9139
|
+
backend: "none",
|
|
9140
|
+
baseTemplate: "app-expo",
|
|
9141
|
+
overlay: null,
|
|
9142
|
+
deployConfig: null,
|
|
9143
|
+
functionsTemplate: null
|
|
9144
|
+
},
|
|
9145
|
+
{
|
|
9146
|
+
builder: "expo",
|
|
9147
|
+
backend: "firebase",
|
|
9148
|
+
baseTemplate: "app-expo",
|
|
9149
|
+
overlay: "overlay-firebase",
|
|
9150
|
+
deployConfig: null,
|
|
9151
|
+
functionsTemplate: "functions-firebase"
|
|
9152
|
+
},
|
|
9153
|
+
{
|
|
9154
|
+
builder: "expo",
|
|
9155
|
+
backend: "supabase",
|
|
9156
|
+
baseTemplate: "app-expo",
|
|
9157
|
+
overlay: "overlay-supabase",
|
|
9158
|
+
deployConfig: null,
|
|
9159
|
+
functionsTemplate: "functions-supabase"
|
|
9160
|
+
},
|
|
9161
|
+
{
|
|
9162
|
+
builder: "demo",
|
|
9163
|
+
backend: "none",
|
|
9164
|
+
baseTemplate: "app-demo",
|
|
9165
|
+
overlay: null,
|
|
9166
|
+
deployConfig: null,
|
|
9167
|
+
functionsTemplate: null
|
|
9168
|
+
}
|
|
9086
9169
|
];
|
|
9087
9170
|
function comboKey(builder, backend) {
|
|
9088
9171
|
return `${builder}-${backend}`;
|
|
@@ -9095,7 +9178,9 @@ function getScaffoldRow(builder, backend) {
|
|
|
9095
9178
|
const key = comboKey(builder, backend);
|
|
9096
9179
|
const row = ROWS_BY_KEY.get(key);
|
|
9097
9180
|
if (!row) {
|
|
9098
|
-
throw new Error(
|
|
9181
|
+
throw new Error(
|
|
9182
|
+
`Unsupported scaffold combo: ${key}. Supported: ${[...ROWS_BY_KEY.keys()].join(", ")}`
|
|
9183
|
+
);
|
|
9099
9184
|
}
|
|
9100
9185
|
return row;
|
|
9101
9186
|
}
|
|
@@ -9251,13 +9336,16 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9251
9336
|
const variantFile = `src/config/providers.${appTemplate}.ts.example`;
|
|
9252
9337
|
if (overlayFiles.includes(variantFile)) continue;
|
|
9253
9338
|
}
|
|
9254
|
-
const providersVariant = file.match(
|
|
9339
|
+
const providersVariant = file.match(
|
|
9340
|
+
/^src\/config\/providers\.(\w+)\.ts\.example$/
|
|
9341
|
+
);
|
|
9255
9342
|
if (providersVariant) {
|
|
9256
9343
|
if (providersVariant[1] !== appTemplate) continue;
|
|
9257
9344
|
const destPath2 = joinPath(appDir, "src/config/providers.ts");
|
|
9258
9345
|
await ensureDir(getDirname(destPath2));
|
|
9259
|
-
await copy(joinPath(overlayDir, file), destPath2);
|
|
9260
|
-
if (await isTextFile(destPath2))
|
|
9346
|
+
await copy(joinPath(overlayDir, file), destPath2, { overwrite: true });
|
|
9347
|
+
if (await isTextFile(destPath2))
|
|
9348
|
+
await replacePlaceholders(destPath2, replacements);
|
|
9261
9349
|
continue;
|
|
9262
9350
|
}
|
|
9263
9351
|
const sourcePath = joinPath(overlayDir, file);
|
|
@@ -9267,7 +9355,7 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9267
9355
|
}
|
|
9268
9356
|
const destPath = joinPath(appDir, destFileName);
|
|
9269
9357
|
await ensureDir(getDirname(destPath));
|
|
9270
|
-
await copy(sourcePath, destPath);
|
|
9358
|
+
await copy(sourcePath, destPath, { overwrite: true });
|
|
9271
9359
|
if (await isTextFile(destPath)) {
|
|
9272
9360
|
await replacePlaceholders(destPath, replacements);
|
|
9273
9361
|
}
|
|
@@ -9282,16 +9370,28 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9282
9370
|
}
|
|
9283
9371
|
if (deployConfig === "vercel-supabase") {
|
|
9284
9372
|
const vercelPath = joinPath(appDir, "vercel.json");
|
|
9285
|
-
const headersFragmentPath = joinPath(
|
|
9373
|
+
const headersFragmentPath = joinPath(
|
|
9374
|
+
overlayDir,
|
|
9375
|
+
"vercel.headers.example"
|
|
9376
|
+
);
|
|
9286
9377
|
const fullVercelPath = joinPath(overlayDir, "vercel.json.example");
|
|
9287
9378
|
if (pathExists(vercelPath) && pathExists(headersFragmentPath)) {
|
|
9288
9379
|
const vercelJson = readSync(vercelPath, { format: "json" });
|
|
9289
|
-
const headersFragment = readSync(headersFragmentPath, {
|
|
9290
|
-
|
|
9291
|
-
|
|
9380
|
+
const headersFragment = readSync(headersFragmentPath, {
|
|
9381
|
+
format: "json"
|
|
9382
|
+
});
|
|
9383
|
+
vercelJson.headers = [
|
|
9384
|
+
...vercelJson.headers ?? [],
|
|
9385
|
+
...headersFragment
|
|
9386
|
+
];
|
|
9387
|
+
await write(vercelPath, vercelJson, {
|
|
9388
|
+
format: "json",
|
|
9389
|
+
overwrite: true
|
|
9390
|
+
});
|
|
9292
9391
|
} else if (pathExists(fullVercelPath)) {
|
|
9293
9392
|
await copy(fullVercelPath, vercelPath);
|
|
9294
|
-
if (await isTextFile(vercelPath))
|
|
9393
|
+
if (await isTextFile(vercelPath))
|
|
9394
|
+
await replacePlaceholders(vercelPath, replacements);
|
|
9295
9395
|
}
|
|
9296
9396
|
}
|
|
9297
9397
|
}
|
|
@@ -9310,23 +9410,33 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9310
9410
|
overwrite: true
|
|
9311
9411
|
});
|
|
9312
9412
|
if (row.functionsTemplate) {
|
|
9313
|
-
const functionsRootDir = joinPath(appDir, "functions");
|
|
9314
9413
|
const functionsTemplateName = row.functionsTemplate;
|
|
9315
|
-
const functionsTemplateExists = pathExists(
|
|
9414
|
+
const functionsTemplateExists = pathExists(
|
|
9415
|
+
joinPath(templatesRoot, functionsTemplateName)
|
|
9416
|
+
);
|
|
9316
9417
|
if (!functionsTemplateExists) {
|
|
9317
|
-
log.warn(
|
|
9318
|
-
|
|
9319
|
-
const functionsPackageJson = generatePackageJson(
|
|
9320
|
-
functionsTemplateName,
|
|
9321
|
-
executionMode,
|
|
9322
|
-
{ appName, platform: row.functionsTemplate.replace("functions-", "") }
|
|
9418
|
+
log.warn(
|
|
9419
|
+
`Functions template "${functionsTemplateName}" not found \u2014 skipping functions scaffolding.`
|
|
9323
9420
|
);
|
|
9324
|
-
|
|
9325
|
-
|
|
9326
|
-
|
|
9327
|
-
|
|
9328
|
-
|
|
9329
|
-
|
|
9421
|
+
} else {
|
|
9422
|
+
const isSupabaseFunctions = functionsTemplateName === "functions-supabase";
|
|
9423
|
+
const functionsRootDir = isSupabaseFunctions ? appDir : joinPath(appDir, "functions");
|
|
9424
|
+
if (!isSupabaseFunctions) {
|
|
9425
|
+
const functionsPackageJson = generatePackageJson(
|
|
9426
|
+
functionsTemplateName,
|
|
9427
|
+
executionMode,
|
|
9428
|
+
{
|
|
9429
|
+
appName,
|
|
9430
|
+
platform: row.functionsTemplate.replace("functions-", "")
|
|
9431
|
+
}
|
|
9432
|
+
);
|
|
9433
|
+
const packageJsonPath2 = joinPath(functionsRootDir, "package.json");
|
|
9434
|
+
await ensureDir(functionsRootDir);
|
|
9435
|
+
await write(packageJsonPath2, functionsPackageJson, {
|
|
9436
|
+
format: "json",
|
|
9437
|
+
overwrite: true
|
|
9438
|
+
});
|
|
9439
|
+
}
|
|
9330
9440
|
const templateDir2 = joinPath(templatesRoot, functionsTemplateName);
|
|
9331
9441
|
const templateFiles2 = await glob("**/*", {
|
|
9332
9442
|
cwd: templateDir2,
|
|
@@ -9354,20 +9464,49 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9354
9464
|
}
|
|
9355
9465
|
const deploymentTemplateDir = joinPath(templatesRoot, "root-consumer");
|
|
9356
9466
|
if (deployConfig === "firebase") {
|
|
9357
|
-
const firebaseJsonSource = joinPath(
|
|
9467
|
+
const firebaseJsonSource = joinPath(
|
|
9468
|
+
deploymentTemplateDir,
|
|
9469
|
+
"firebase.json.example"
|
|
9470
|
+
);
|
|
9358
9471
|
if (pathExists(firebaseJsonSource)) {
|
|
9359
9472
|
await copy(firebaseJsonSource, joinPath(appDir, "firebase.json"));
|
|
9360
9473
|
const firebaseJsonDest = joinPath(appDir, "firebase.json");
|
|
9361
|
-
if (await isTextFile(firebaseJsonDest))
|
|
9474
|
+
if (await isTextFile(firebaseJsonDest))
|
|
9475
|
+
await replacePlaceholders(firebaseJsonDest, replacements);
|
|
9476
|
+
if (appTemplate === "nextjs") {
|
|
9477
|
+
const firebaseJson = readSync(firebaseJsonDest, {
|
|
9478
|
+
format: "json"
|
|
9479
|
+
});
|
|
9480
|
+
if (firebaseJson.hosting?.rewrites) {
|
|
9481
|
+
firebaseJson.hosting.rewrites = firebaseJson.hosting.rewrites.filter(
|
|
9482
|
+
(r2) => r2.destination !== "/index.html"
|
|
9483
|
+
);
|
|
9484
|
+
}
|
|
9485
|
+
if (firebaseJson.hosting) {
|
|
9486
|
+
firebaseJson.hosting.public = "out";
|
|
9487
|
+
}
|
|
9488
|
+
await write(firebaseJsonDest, firebaseJson, {
|
|
9489
|
+
format: "json",
|
|
9490
|
+
overwrite: true
|
|
9491
|
+
});
|
|
9492
|
+
}
|
|
9362
9493
|
}
|
|
9363
|
-
const firebasercSource = joinPath(
|
|
9494
|
+
const firebasercSource = joinPath(
|
|
9495
|
+
deploymentTemplateDir,
|
|
9496
|
+
".firebaserc.example"
|
|
9497
|
+
);
|
|
9364
9498
|
if (pathExists(firebasercSource)) {
|
|
9365
9499
|
await copy(firebasercSource, joinPath(appDir, ".firebaserc"));
|
|
9366
9500
|
const firebasercDest = joinPath(appDir, ".firebaserc");
|
|
9367
|
-
if (await isTextFile(firebasercDest))
|
|
9501
|
+
if (await isTextFile(firebasercDest))
|
|
9502
|
+
await replacePlaceholders(firebasercDest, replacements);
|
|
9368
9503
|
}
|
|
9369
9504
|
if (row.functionsTemplate === "functions-firebase") {
|
|
9370
|
-
for (const example of [
|
|
9505
|
+
for (const example of [
|
|
9506
|
+
"firestore.rules.example",
|
|
9507
|
+
"firestore.indexes.json.example",
|
|
9508
|
+
"storage.rules.example"
|
|
9509
|
+
]) {
|
|
9371
9510
|
const src = joinPath(deploymentTemplateDir, example);
|
|
9372
9511
|
if (pathExists(src)) {
|
|
9373
9512
|
await copy(src, joinPath(appDir, example.replace(".example", "")));
|
|
@@ -9375,12 +9514,76 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9375
9514
|
}
|
|
9376
9515
|
}
|
|
9377
9516
|
}
|
|
9517
|
+
if (!deployConfig && backend === "firebase" && row.functionsTemplate) {
|
|
9518
|
+
const firebaseJsonPath = joinPath(appDir, "firebase.json");
|
|
9519
|
+
if (!pathExists(firebaseJsonPath)) {
|
|
9520
|
+
const expoFirebaseJson = {
|
|
9521
|
+
functions: [
|
|
9522
|
+
{
|
|
9523
|
+
source: "functions",
|
|
9524
|
+
codebase: "default",
|
|
9525
|
+
ignore: [
|
|
9526
|
+
"node_modules",
|
|
9527
|
+
".git",
|
|
9528
|
+
"firebase-debug.log",
|
|
9529
|
+
"firebase-debug.*.log",
|
|
9530
|
+
"**/.*",
|
|
9531
|
+
"**/*.test.ts",
|
|
9532
|
+
"**/__tests__/**"
|
|
9533
|
+
],
|
|
9534
|
+
runtime: "nodejs22"
|
|
9535
|
+
}
|
|
9536
|
+
],
|
|
9537
|
+
firestore: {
|
|
9538
|
+
rules: "firestore.rules",
|
|
9539
|
+
indexes: "firestore.indexes.json"
|
|
9540
|
+
},
|
|
9541
|
+
storage: { rules: "storage.rules" },
|
|
9542
|
+
emulators: {
|
|
9543
|
+
auth: { port: 9099 },
|
|
9544
|
+
functions: { port: 5001 },
|
|
9545
|
+
firestore: { port: 8080 },
|
|
9546
|
+
storage: { port: 9199 },
|
|
9547
|
+
ui: { enabled: true, port: 4e3 }
|
|
9548
|
+
}
|
|
9549
|
+
};
|
|
9550
|
+
await write(firebaseJsonPath, expoFirebaseJson, {
|
|
9551
|
+
format: "json",
|
|
9552
|
+
overwrite: true
|
|
9553
|
+
});
|
|
9554
|
+
}
|
|
9555
|
+
const firebasercSource = joinPath(
|
|
9556
|
+
deploymentTemplateDir,
|
|
9557
|
+
".firebaserc.example"
|
|
9558
|
+
);
|
|
9559
|
+
const firebasercDest = joinPath(appDir, ".firebaserc");
|
|
9560
|
+
if (pathExists(firebasercSource) && !pathExists(firebasercDest)) {
|
|
9561
|
+
await copy(firebasercSource, firebasercDest);
|
|
9562
|
+
if (await isTextFile(firebasercDest))
|
|
9563
|
+
await replacePlaceholders(firebasercDest, replacements);
|
|
9564
|
+
}
|
|
9565
|
+
for (const example of [
|
|
9566
|
+
"firestore.rules.example",
|
|
9567
|
+
"firestore.indexes.json.example",
|
|
9568
|
+
"storage.rules.example"
|
|
9569
|
+
]) {
|
|
9570
|
+
const src = joinPath(deploymentTemplateDir, example);
|
|
9571
|
+
const dest = joinPath(appDir, example.replace(".example", ""));
|
|
9572
|
+
if (pathExists(src) && !pathExists(dest)) {
|
|
9573
|
+
await copy(src, dest);
|
|
9574
|
+
}
|
|
9575
|
+
}
|
|
9576
|
+
}
|
|
9378
9577
|
if (deployConfig === "vercel-vercel") {
|
|
9379
|
-
const vercelJsonSource = joinPath(
|
|
9578
|
+
const vercelJsonSource = joinPath(
|
|
9579
|
+
deploymentTemplateDir,
|
|
9580
|
+
"vercel.json.example"
|
|
9581
|
+
);
|
|
9380
9582
|
if (pathExists(vercelJsonSource)) {
|
|
9381
9583
|
await copy(vercelJsonSource, joinPath(appDir, "vercel.json"));
|
|
9382
9584
|
const vercelJsonDest = joinPath(appDir, "vercel.json");
|
|
9383
|
-
if (await isTextFile(vercelJsonDest))
|
|
9585
|
+
if (await isTextFile(vercelJsonDest))
|
|
9586
|
+
await replacePlaceholders(vercelJsonDest, replacements);
|
|
9384
9587
|
}
|
|
9385
9588
|
}
|
|
9386
9589
|
const backendInfo = row.functionsTemplate ? ` with ${row.functionsTemplate.replace("functions-", "")} functions` : "";
|
|
@@ -9417,23 +9620,25 @@ init_cli_input();
|
|
|
9417
9620
|
init_cli_output();
|
|
9418
9621
|
init_pathResolver();
|
|
9419
9622
|
var SHOW_WIP2 = process.env.SHOW_WIP === "true" || process.argv.includes("--wip");
|
|
9420
|
-
|
|
9421
|
-
|
|
9422
|
-
|
|
9423
|
-
|
|
9424
|
-
|
|
9425
|
-
}
|
|
9426
|
-
|
|
9427
|
-
|
|
9428
|
-
|
|
9429
|
-
|
|
9430
|
-
|
|
9431
|
-
|
|
9432
|
-
|
|
9433
|
-
|
|
9434
|
-
]
|
|
9435
|
-
|
|
9436
|
-
|
|
9623
|
+
async function collectAppConfig(appName) {
|
|
9624
|
+
const answers = await runQuestionnaire(APP_QUESTIONNAIRE, {}, SHOW_WIP2, {
|
|
9625
|
+
selection: askForSelection,
|
|
9626
|
+
confirmation: askForConfirmation,
|
|
9627
|
+
input: askForInput
|
|
9628
|
+
});
|
|
9629
|
+
const framework = answers.framework || "vite";
|
|
9630
|
+
const needsBackend = answers.needsBackend || false;
|
|
9631
|
+
const defaultPlatform = framework === "nextjs" ? "vercel" : "firebase";
|
|
9632
|
+
return {
|
|
9633
|
+
template: framework,
|
|
9634
|
+
needsBackend,
|
|
9635
|
+
backendPlatform: needsBackend ? answers.backendPlatform || defaultPlatform : void 0,
|
|
9636
|
+
needsCRUD: false,
|
|
9637
|
+
selectedEntities: [],
|
|
9638
|
+
userAuth: "none",
|
|
9639
|
+
billing: false,
|
|
9640
|
+
features: []
|
|
9641
|
+
};
|
|
9437
9642
|
}
|
|
9438
9643
|
function calculateRelativePath(from, to) {
|
|
9439
9644
|
try {
|
|
@@ -9546,71 +9751,22 @@ async function main(options) {
|
|
|
9546
9751
|
let appNames = [];
|
|
9547
9752
|
const appConfigs = {};
|
|
9548
9753
|
let anyAppNeedsBackend = false;
|
|
9549
|
-
|
|
9550
|
-
|
|
9551
|
-
""
|
|
9552
|
-
|
|
9553
|
-
|
|
9554
|
-
|
|
9555
|
-
if (isReservedAppName(trimmedName)) {
|
|
9556
|
-
log.warn(`'${trimmedName}' is reserved for framework demos.`);
|
|
9557
|
-
} else if (!isValidFileName(trimmedName)) {
|
|
9558
|
-
log.warn(
|
|
9559
|
-
`Invalid app name. Use only letters, numbers, dashes (-), and underscores (_).`
|
|
9560
|
-
);
|
|
9561
|
-
} else {
|
|
9562
|
-
appNames.push(trimmedName);
|
|
9563
|
-
const framework = await askForSelection(
|
|
9564
|
-
`Builder for "${trimmedName}"?`,
|
|
9565
|
-
[
|
|
9566
|
-
{
|
|
9567
|
-
title: "Vite \u2014 SPA/SaaS (client-side rendering, fast dev)",
|
|
9568
|
-
value: "vite"
|
|
9569
|
-
},
|
|
9570
|
-
{
|
|
9571
|
-
title: "Next.js \u2014 Static content/SEO (SSR, SSG) \u2014 DoNotDev support: BETA",
|
|
9572
|
-
value: "nextjs"
|
|
9573
|
-
},
|
|
9574
|
-
{
|
|
9575
|
-
title: "Expo \u2014 Mobile app (iOS + Android, single codebase)",
|
|
9576
|
-
value: "expo"
|
|
9577
|
-
}
|
|
9578
|
-
],
|
|
9579
|
-
0
|
|
9580
|
-
);
|
|
9581
|
-
const backendValue = await askForSelection(
|
|
9582
|
-
`Backend for "${trimmedName}"?`,
|
|
9583
|
-
[...BACKEND_CHOICES],
|
|
9584
|
-
getDefaultBackendIndex(framework)
|
|
9585
|
-
);
|
|
9586
|
-
const needsBackend = backendValue !== "none";
|
|
9587
|
-
if (needsBackend) anyAppNeedsBackend = true;
|
|
9588
|
-
appConfigs[trimmedName] = {
|
|
9589
|
-
template: framework,
|
|
9590
|
-
needsBackend,
|
|
9591
|
-
backendPlatform: needsBackend ? backendValue : void 0,
|
|
9592
|
-
needsCRUD: false,
|
|
9593
|
-
selectedEntities: [],
|
|
9594
|
-
userAuth: "none",
|
|
9595
|
-
billing: false,
|
|
9596
|
-
features: []
|
|
9597
|
-
};
|
|
9598
|
-
}
|
|
9599
|
-
}
|
|
9600
|
-
while (appNames.length > 0) {
|
|
9601
|
-
const appName = await askForInput("App name (press Enter to finish)", "");
|
|
9602
|
-
if (!appName || appName.trim() === "") {
|
|
9754
|
+
let isFirstApp = true;
|
|
9755
|
+
while (true) {
|
|
9756
|
+
const prompt = isFirstApp ? "What's your first app name? (press Enter to skip)" : "App name (press Enter to finish)";
|
|
9757
|
+
const appNameInput = await askForInput(prompt, "");
|
|
9758
|
+
if (!appNameInput || appNameInput.trim() === "") {
|
|
9759
|
+
if (isFirstApp) break;
|
|
9603
9760
|
break;
|
|
9604
9761
|
}
|
|
9605
|
-
const trimmedName =
|
|
9762
|
+
const trimmedName = appNameInput.trim();
|
|
9763
|
+
isFirstApp = false;
|
|
9606
9764
|
if (appNames.includes(trimmedName)) {
|
|
9607
9765
|
log.warn(`'${trimmedName}' already exists. Choose a different name.`);
|
|
9608
9766
|
continue;
|
|
9609
9767
|
}
|
|
9610
9768
|
if (isReservedAppName(trimmedName)) {
|
|
9611
|
-
log.warn(
|
|
9612
|
-
`'${trimmedName}' is reserved for framework demos. Choose a different name.`
|
|
9613
|
-
);
|
|
9769
|
+
log.warn(`'${trimmedName}' is reserved for framework demos.`);
|
|
9614
9770
|
continue;
|
|
9615
9771
|
}
|
|
9616
9772
|
if (!isValidFileName(trimmedName)) {
|
|
@@ -9620,37 +9776,10 @@ async function main(options) {
|
|
|
9620
9776
|
continue;
|
|
9621
9777
|
}
|
|
9622
9778
|
appNames.push(trimmedName);
|
|
9623
|
-
|
|
9624
|
-
|
|
9625
|
-
|
|
9626
|
-
|
|
9627
|
-
title: "Vite \u2014 SPA/SaaS (client-side rendering, fast dev)",
|
|
9628
|
-
value: "vite"
|
|
9629
|
-
},
|
|
9630
|
-
{
|
|
9631
|
-
title: "Next.js \u2014 Static content/SEO (SSR, SSG) \u2014 DoNotDev support: BETA",
|
|
9632
|
-
value: "nextjs"
|
|
9633
|
-
}
|
|
9634
|
-
],
|
|
9635
|
-
0
|
|
9636
|
-
);
|
|
9637
|
-
const backendValue = await askForSelection(
|
|
9638
|
-
`Backend for "${trimmedName}"?`,
|
|
9639
|
-
[...BACKEND_CHOICES],
|
|
9640
|
-
getDefaultBackendIndex(framework)
|
|
9641
|
-
);
|
|
9642
|
-
const needsBackend = backendValue !== "none";
|
|
9643
|
-
if (needsBackend) anyAppNeedsBackend = true;
|
|
9644
|
-
appConfigs[trimmedName] = {
|
|
9645
|
-
template: framework,
|
|
9646
|
-
needsBackend,
|
|
9647
|
-
backendPlatform: needsBackend ? backendValue : void 0,
|
|
9648
|
-
needsCRUD: false,
|
|
9649
|
-
selectedEntities: [],
|
|
9650
|
-
userAuth: "none",
|
|
9651
|
-
billing: false,
|
|
9652
|
-
features: []
|
|
9653
|
-
};
|
|
9779
|
+
Me(`Configuring "${trimmedName}"...`, "\u2699\uFE0F");
|
|
9780
|
+
const config = await collectAppConfig(trimmedName);
|
|
9781
|
+
appConfigs[trimmedName] = config;
|
|
9782
|
+
if (config.needsBackend) anyAppNeedsBackend = true;
|
|
9654
9783
|
}
|
|
9655
9784
|
let installDemoApp = await askForConfirmation(
|
|
9656
9785
|
"Would you like to install the demo app? (component showcase)",
|