@donotdev/cli 0.0.14 → 0.0.15
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 +356 -88
- package/dist/bin/commands/agent-setup.js +7 -1
- package/dist/bin/commands/build.js +118 -38
- package/dist/bin/commands/bump.js +74 -28
- package/dist/bin/commands/cacheout.js +37 -9
- package/dist/bin/commands/create-app.js +222 -115
- package/dist/bin/commands/create-project.js +455 -140
- package/dist/bin/commands/deploy.js +1736 -697
- package/dist/bin/commands/dev.js +138 -23
- package/dist/bin/commands/emu.js +215 -58
- package/dist/bin/commands/format.js +37 -9
- package/dist/bin/commands/lint.js +37 -9
- package/dist/bin/commands/preview.js +142 -23
- package/dist/bin/commands/supabase-setup.d.ts +6 -0
- package/dist/bin/commands/supabase-setup.d.ts.map +1 -0
- package/dist/bin/commands/supabase-setup.js +7 -0
- package/dist/bin/commands/supabase-setup.js.map +1 -0
- package/dist/bin/commands/sync-secrets.js +211 -34
- package/dist/bin/commands/type-check.d.ts +14 -0
- package/dist/bin/commands/type-check.d.ts.map +1 -0
- package/dist/bin/commands/type-check.js +314 -0
- package/dist/bin/commands/type-check.js.map +1 -0
- package/dist/bin/commands/wai.js +3 -1
- package/dist/bin/dndev.js +27 -2
- package/dist/bin/donotdev.js +27 -2
- package/dist/index.js +3960 -3015
- package/package.json +2 -2
- package/templates/app-demo/src/App.tsx.example +1 -0
- package/templates/app-demo/src/pages/FullPage.tsx.example +2 -2
- package/templates/app-demo/src/pages/components/DemoLayout.tsx.example +2 -2
- package/templates/app-demo/src/themes.css.example +5 -12
- package/templates/app-expo/.env.example +64 -0
- package/templates/app-expo/.expo/README.md.example +5 -0
- package/templates/app-expo/.gitignore.example +36 -0
- package/templates/app-expo/README.md.example +58 -0
- package/templates/app-expo/app/.gitkeep +2 -0
- package/templates/app-expo/app/_layout.tsx.example +41 -0
- package/templates/app-expo/app/form.tsx.example +52 -0
- package/templates/app-expo/app/index.tsx.example +89 -0
- package/templates/app-expo/app/list.tsx.example +32 -0
- package/templates/app-expo/app/profile.tsx.example +76 -0
- package/templates/app-expo/app/signin.tsx.example +53 -0
- package/templates/app-expo/app.json.example +39 -0
- package/templates/app-expo/babel.config.js.example +10 -0
- package/templates/app-expo/eas.json.example +20 -0
- package/templates/app-expo/expo-env.d.ts.example +4 -0
- package/templates/app-expo/metro.config.js.example +20 -0
- package/templates/app-expo/service-account-key.json.example +12 -0
- package/templates/app-expo/tsconfig.json.example +19 -0
- package/templates/app-next/.env.example +4 -33
- package/templates/app-next/src/app/ClientLayout.tsx.example +2 -0
- package/templates/app-next/src/app/layout.tsx.example +7 -6
- package/templates/app-next/src/globals.css.example +2 -11
- package/templates/app-next/src/pages/HomePage.tsx.example +1 -1
- package/templates/app-next/src/themes.css.example +10 -13
- package/templates/app-vite/.env.example +3 -32
- package/templates/app-vite/index.html.example +2 -24
- package/templates/app-vite/src/App.tsx.example +2 -0
- package/templates/app-vite/src/globals.css.example +2 -12
- package/templates/app-vite/src/pages/FormPageExample.tsx.example +1 -2
- package/templates/app-vite/src/pages/HomePage.tsx.example +1 -1
- package/templates/app-vite/src/themes.css.example +109 -79
- package/templates/app-vite/vercel.json.example +11 -0
- package/templates/functions-firebase/build.mjs.example +2 -72
- package/templates/functions-firebase/functions-firebase/.env.example.example +23 -25
- package/templates/functions-firebase/functions-firebase/build.mjs.example +2 -72
- package/templates/functions-firebase/functions-firebase/tsconfig.json.example +1 -1
- package/templates/functions-supabase/supabase/functions/cancel-subscription/index.ts.example +7 -0
- package/templates/functions-supabase/supabase/functions/change-plan/index.ts.example +11 -0
- package/templates/functions-supabase/supabase/functions/create-checkout-session/index.ts.example +11 -0
- package/templates/functions-supabase/supabase/functions/create-customer-portal/index.ts.example +7 -0
- package/templates/functions-supabase/supabase/functions/crud/index.ts.example +16 -0
- package/templates/functions-supabase/supabase/functions/delete-account/index.ts.example +7 -0
- package/templates/functions-supabase/supabase/functions/get-custom-claims/index.ts.example +7 -0
- package/templates/functions-supabase/supabase/functions/get-user-auth-status/index.ts.example +7 -0
- package/templates/functions-supabase/supabase/functions/refresh-subscription-status/index.ts.example +7 -0
- package/templates/functions-supabase/supabase/functions/remove-custom-claims/index.ts.example +7 -0
- package/templates/functions-supabase/supabase/functions/set-custom-claims/index.ts.example +7 -0
- package/templates/functions-supabase/supabase/migrations/20250101000000_idempotency.sql +24 -0
- package/templates/functions-supabase/supabase/migrations/20250101000001_rate_limits.sql +22 -0
- package/templates/functions-supabase/supabase/migrations/20250101000002_cleanup_jobs.sql +28 -0
- package/templates/functions-supabase/supabase/migrations/20250101000003_operation_metrics.sql +28 -0
- package/templates/functions-vercel/functions-vercel/tsconfig.json.example +1 -1
- package/templates/functions-vercel/functions-vercel/vercel.json.example +1 -1
- package/templates/functions-vercel/vercel.json.example +1 -1
- package/templates/github/github/workflows/firebase-deploy.yml.example +1 -1
- package/templates/github/workflows/firebase-deploy.yml.example +1 -1
- package/templates/overlay-firebase/env.fragment.example +34 -0
- package/templates/overlay-firebase/env.fragment.expo.example +34 -0
- package/templates/overlay-firebase/env.fragment.nextjs.example +34 -0
- package/templates/overlay-firebase/src/config/providers.expo.ts.example +49 -0
- package/templates/overlay-firebase/src/config/providers.ts.example +23 -0
- package/templates/overlay-supabase/env.fragment.example +7 -0
- package/templates/overlay-supabase/env.fragment.expo.example +7 -0
- package/templates/overlay-supabase/env.fragment.nextjs.example +7 -0
- package/templates/overlay-supabase/src/config/providers.expo.ts.example +35 -0
- package/templates/overlay-supabase/src/config/providers.ts.example +33 -0
- package/templates/overlay-supabase/vercel.headers.example +23 -0
- package/templates/overlay-supabase/vercel.json.example +22 -0
- package/templates/overlay-vercel/env.fragment.example +34 -0
- package/templates/overlay-vercel/env.fragment.nextjs.example +34 -0
- package/templates/overlay-vercel/src/config/providers.ts.example +24 -0
- package/templates/root-consumer/.claude/agents/architect.md.example +2 -310
- package/templates/root-consumer/.claude/agents/builder.md.example +2 -326
- package/templates/root-consumer/.claude/agents/coder.md.example +2 -83
- package/templates/root-consumer/.claude/agents/extractor.md.example +2 -231
- package/templates/root-consumer/.claude/agents/polisher.md.example +2 -132
- package/templates/root-consumer/.claude/agents/prompt-engineer.md.example +2 -81
- package/templates/root-consumer/.claude/commands/grill.md.example +30 -0
- package/templates/root-consumer/.claude/commands/techdebt.md.example +28 -0
- package/templates/root-consumer/.clinerules.example +1 -0
- package/templates/root-consumer/.cursor/rules/no-docs.mdc.example +15 -0
- package/templates/root-consumer/.cursorrules.example +1 -0
- package/templates/root-consumer/.github/copilot-instructions.md.example +1 -0
- package/templates/root-consumer/.windsurfrules.example +1 -0
- package/templates/root-consumer/AI.md.example +29 -123
- package/templates/root-consumer/CLAUDE.md.example +1 -134
- package/templates/root-consumer/CONVENTIONS.md.example +1 -0
- package/templates/root-consumer/GEMINI.md.example +1 -0
- package/templates/root-consumer/firebase.json.example +1 -1
- package/templates/root-consumer/guides/dndev/AGENT_START_HERE.md.example +20 -0
- package/templates/root-consumer/guides/dndev/COMPONENTS_ADV.md.example +0 -18
- package/templates/root-consumer/guides/dndev/COMPONENTS_UI.md.example +1 -1
- package/templates/root-consumer/guides/dndev/ENV_SETUP.md.example +99 -30
- package/templates/root-consumer/guides/dndev/INDEX.md.example +3 -1
- package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +143 -12
- package/templates/root-consumer/guides/dndev/SETUP_FIREBASE.md.example +9 -3
- package/templates/root-consumer/guides/dndev/SETUP_SOC2.md.example +234 -0
- package/templates/root-consumer/guides/dndev/SETUP_SUPABASE.md.example +124 -0
- package/templates/root-consumer/guides/dndev/SETUP_THEMES.md.example +6 -2
- package/templates/root-consumer/guides/dndev/SETUP_VERCEL.md.example +176 -0
- package/templates/root-consumer/guides/dndev/USE_ROUTING.md.example +5 -9
- package/templates/root-consumer/guides/dndev/essences_reference.css.example +174 -0
- package/templates/root-consumer/guides/wai-way/agents/builder.md.example +10 -0
- package/templates/root-consumer/guides/wai-way/agents/extractor.md.example +25 -5
- package/templates/root-consumer/guides/wai-way/agents/polisher.md.example +13 -2
- package/templates/root-consumer/guides/wai-way/blueprints/0_brainstorm.md.example +2 -2
- package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +47 -11
- package/templates/root-consumer/guides/wai-way/blueprints/3_compose.md.example +15 -4
- package/templates/root-consumer/guides/wai-way/spec_template.md.example +7 -6
- package/templates/app-payload/.env.example +0 -28
- package/templates/app-payload/README.md.example +0 -233
- package/templates/app-payload/collections/Company.ts.example +0 -125
- package/templates/app-payload/collections/Hero.ts.example +0 -62
- package/templates/app-payload/collections/Media.ts.example +0 -41
- package/templates/app-payload/collections/Products.ts.example +0 -115
- package/templates/app-payload/collections/Services.ts.example +0 -104
- package/templates/app-payload/collections/Testimonials.ts.example +0 -92
- package/templates/app-payload/collections/Users.ts.example +0 -35
- package/templates/app-payload/src/server.ts.example +0 -79
- package/templates/app-payload/tsconfig.json.example +0 -24
|
@@ -7884,16 +7884,19 @@ function getBinPath(binaryName) {
|
|
|
7884
7884
|
return binaryName;
|
|
7885
7885
|
}
|
|
7886
7886
|
function detectExecutionMode() {
|
|
7887
|
-
const fileUrlPath =
|
|
7888
|
-
if (
|
|
7889
|
-
return "
|
|
7887
|
+
const fileUrlPath = fileURLToPath2(import.meta.url);
|
|
7888
|
+
if (fileUrlPath.includes("node_modules")) {
|
|
7889
|
+
return "published";
|
|
7890
7890
|
}
|
|
7891
|
-
|
|
7891
|
+
if (fileUrlPath.includes("/dist/")) {
|
|
7892
|
+
return "published";
|
|
7893
|
+
}
|
|
7894
|
+
return "development";
|
|
7892
7895
|
}
|
|
7893
7896
|
function getTemplatesRoot() {
|
|
7894
7897
|
const mode = detectExecutionMode();
|
|
7895
7898
|
if (mode === "development") {
|
|
7896
|
-
const fileUrlPath =
|
|
7899
|
+
const fileUrlPath = fileURLToPath2(import.meta.url);
|
|
7897
7900
|
const frameworkRoot = normalizePath(dirname2(fileUrlPath), "../../../..");
|
|
7898
7901
|
return normalizePath(frameworkRoot, PACKAGE_PATHS.CLI, "templates");
|
|
7899
7902
|
} else {
|
|
@@ -8173,18 +8176,7 @@ var init_utils = __esm({
|
|
|
8173
8176
|
}
|
|
8174
8177
|
});
|
|
8175
8178
|
|
|
8176
|
-
// packages/cli/src/bin/commands/create-app.ts
|
|
8177
|
-
init_utils();
|
|
8178
|
-
|
|
8179
|
-
// packages/tooling/src/index.ts
|
|
8180
|
-
init_utils();
|
|
8181
|
-
|
|
8182
|
-
// packages/tooling/src/cli/index.ts
|
|
8183
|
-
init_utils();
|
|
8184
|
-
|
|
8185
8179
|
// packages/tooling/src/utils/cli-input.ts
|
|
8186
|
-
init_utils();
|
|
8187
|
-
init_dist2();
|
|
8188
8180
|
async function askForInput(message, defaultValue = "") {
|
|
8189
8181
|
const result = await he({
|
|
8190
8182
|
message,
|
|
@@ -8225,6 +8217,22 @@ async function askForSelection(message, choices, defaultValue = 0) {
|
|
|
8225
8217
|
}
|
|
8226
8218
|
return result;
|
|
8227
8219
|
}
|
|
8220
|
+
var init_cli_input = __esm({
|
|
8221
|
+
"packages/tooling/src/utils/cli-input.ts"() {
|
|
8222
|
+
"use strict";
|
|
8223
|
+
init_utils();
|
|
8224
|
+
init_dist2();
|
|
8225
|
+
}
|
|
8226
|
+
});
|
|
8227
|
+
|
|
8228
|
+
// packages/cli/src/bin/commands/create-app.ts
|
|
8229
|
+
init_utils();
|
|
8230
|
+
|
|
8231
|
+
// packages/tooling/src/index.ts
|
|
8232
|
+
init_utils();
|
|
8233
|
+
|
|
8234
|
+
// packages/tooling/src/cli/index.ts
|
|
8235
|
+
init_utils();
|
|
8228
8236
|
|
|
8229
8237
|
// packages/tooling/src/utils/create-utils.ts
|
|
8230
8238
|
init_utils();
|
|
@@ -8460,6 +8468,10 @@ var APP_QUESTIONNAIRE = [
|
|
|
8460
8468
|
{
|
|
8461
8469
|
title: "Next.js \u2014 Static content/SEO (SSR, SSG) \u2014 BETA",
|
|
8462
8470
|
value: "nextjs"
|
|
8471
|
+
},
|
|
8472
|
+
{
|
|
8473
|
+
title: "Expo \u2014 Mobile app (iOS + Android)",
|
|
8474
|
+
value: "expo"
|
|
8463
8475
|
}
|
|
8464
8476
|
]
|
|
8465
8477
|
},
|
|
@@ -8486,6 +8498,10 @@ var APP_QUESTIONNAIRE = [
|
|
|
8486
8498
|
{
|
|
8487
8499
|
title: "Vercel \u2014 Serverless functions (edge + node.js)",
|
|
8488
8500
|
value: "vercel"
|
|
8501
|
+
},
|
|
8502
|
+
{
|
|
8503
|
+
title: "Supabase \u2014 Postgres + Auth + Storage",
|
|
8504
|
+
value: "supabase"
|
|
8489
8505
|
}
|
|
8490
8506
|
]
|
|
8491
8507
|
}
|
|
@@ -8552,6 +8568,7 @@ async function runQuestionnaire(questions, initialAnswers, showWIP, askFor) {
|
|
|
8552
8568
|
|
|
8553
8569
|
// packages/tooling/src/scaffolding/create-app.ts
|
|
8554
8570
|
init_utils();
|
|
8571
|
+
init_cli_input();
|
|
8555
8572
|
init_cli_output();
|
|
8556
8573
|
|
|
8557
8574
|
// packages/tooling/src/utils/dependency-resolver.ts
|
|
@@ -8585,6 +8602,15 @@ function generateScripts(templateName, options) {
|
|
|
8585
8602
|
scripts.preview = "next start";
|
|
8586
8603
|
scripts.lint = "eslint src/";
|
|
8587
8604
|
scripts["type-check"] = "tsc --noEmit";
|
|
8605
|
+
} else if (templateName.includes("expo")) {
|
|
8606
|
+
scripts.dev = "expo start";
|
|
8607
|
+
scripts.start = "expo start";
|
|
8608
|
+
scripts.android = "expo start --android";
|
|
8609
|
+
scripts.ios = "expo start --ios";
|
|
8610
|
+
scripts.web = "expo start --web";
|
|
8611
|
+
scripts.build = "expo export";
|
|
8612
|
+
scripts.lint = "eslint .";
|
|
8613
|
+
scripts["type-check"] = "tsc --noEmit";
|
|
8588
8614
|
} else if (templateName === "consumer-root") {
|
|
8589
8615
|
scripts.dev = "turbo run dev";
|
|
8590
8616
|
scripts.build = "turbo run build";
|
|
@@ -8673,7 +8699,7 @@ function generatePackageJson(templateName, mode, options = {}) {
|
|
|
8673
8699
|
result.main = "./index.ts";
|
|
8674
8700
|
result.types = "./index.ts";
|
|
8675
8701
|
}
|
|
8676
|
-
if (templateName.includes("vite") || templateName.includes("nextjs") || templateName.includes("functions")) {
|
|
8702
|
+
if (templateName.includes("vite") || templateName.includes("nextjs") || templateName.includes("expo") || templateName.includes("functions")) {
|
|
8677
8703
|
if (!dependencies.entities) {
|
|
8678
8704
|
dependencies.entities = "workspace:*";
|
|
8679
8705
|
}
|
|
@@ -8721,6 +8747,40 @@ function generatePackageJson(templateName, mode, options = {}) {
|
|
|
8721
8747
|
// packages/tooling/src/scaffolding/create-app.ts
|
|
8722
8748
|
init_pathResolver();
|
|
8723
8749
|
init_pathResolver();
|
|
8750
|
+
|
|
8751
|
+
// packages/tooling/src/scaffolding/scaffold-matrix.ts
|
|
8752
|
+
init_utils();
|
|
8753
|
+
var MATRIX = [
|
|
8754
|
+
{ builder: "vite", backend: "none", baseTemplate: "app-vite", overlay: null, deployConfig: null, functionsTemplate: null },
|
|
8755
|
+
{ builder: "vite", backend: "firebase", baseTemplate: "app-vite", overlay: "overlay-firebase", deployConfig: "firebase", functionsTemplate: "functions-firebase" },
|
|
8756
|
+
{ builder: "vite", backend: "supabase", baseTemplate: "app-vite", overlay: "overlay-supabase", deployConfig: "vercel-supabase", functionsTemplate: null },
|
|
8757
|
+
{ builder: "vite", backend: "vercel", baseTemplate: "app-vite", overlay: "overlay-vercel", deployConfig: "vercel-vercel", functionsTemplate: "functions-vercel" },
|
|
8758
|
+
{ builder: "nextjs", backend: "none", baseTemplate: "app-next", overlay: null, deployConfig: null, functionsTemplate: null },
|
|
8759
|
+
{ builder: "nextjs", backend: "firebase", baseTemplate: "app-next", overlay: "overlay-firebase", deployConfig: "firebase", functionsTemplate: "functions-firebase" },
|
|
8760
|
+
{ builder: "nextjs", backend: "supabase", baseTemplate: "app-next", overlay: "overlay-supabase", deployConfig: "vercel-supabase", functionsTemplate: null },
|
|
8761
|
+
{ builder: "nextjs", backend: "vercel", baseTemplate: "app-next", overlay: "overlay-vercel", deployConfig: "vercel-vercel", functionsTemplate: "functions-vercel" },
|
|
8762
|
+
{ builder: "expo", backend: "none", baseTemplate: "app-expo", overlay: null, deployConfig: null, functionsTemplate: null },
|
|
8763
|
+
{ builder: "expo", backend: "firebase", baseTemplate: "app-expo", overlay: "overlay-firebase", deployConfig: null, functionsTemplate: "functions-firebase" },
|
|
8764
|
+
{ builder: "expo", backend: "supabase", baseTemplate: "app-expo", overlay: "overlay-supabase", deployConfig: null, functionsTemplate: null },
|
|
8765
|
+
{ builder: "demo", backend: "none", baseTemplate: "app-demo", overlay: null, deployConfig: null, functionsTemplate: null }
|
|
8766
|
+
];
|
|
8767
|
+
function comboKey(builder, backend) {
|
|
8768
|
+
return `${builder}-${backend}`;
|
|
8769
|
+
}
|
|
8770
|
+
var ROWS_BY_KEY = /* @__PURE__ */ new Map();
|
|
8771
|
+
for (const row of MATRIX) {
|
|
8772
|
+
ROWS_BY_KEY.set(comboKey(row.builder, row.backend), row);
|
|
8773
|
+
}
|
|
8774
|
+
function getScaffoldRow(builder, backend) {
|
|
8775
|
+
const key = comboKey(builder, backend);
|
|
8776
|
+
const row = ROWS_BY_KEY.get(key);
|
|
8777
|
+
if (!row) {
|
|
8778
|
+
throw new Error(`Unsupported scaffold combo: ${key}. Supported: ${[...ROWS_BY_KEY.keys()].join(", ")}`);
|
|
8779
|
+
}
|
|
8780
|
+
return row;
|
|
8781
|
+
}
|
|
8782
|
+
|
|
8783
|
+
// packages/tooling/src/scaffolding/create-app.ts
|
|
8724
8784
|
var SHOW_WIP = process.env.SHOW_WIP === "true" || process.argv.includes("--wip");
|
|
8725
8785
|
async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
8726
8786
|
const isInteractive = !appName || !appConfig;
|
|
@@ -8806,14 +8866,19 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
8806
8866
|
const s = Y2();
|
|
8807
8867
|
s.start(`Creating app: ${appName}`);
|
|
8808
8868
|
await ensureDir(appDir);
|
|
8809
|
-
const
|
|
8869
|
+
const builder = appTemplate;
|
|
8870
|
+
const backend = appConfig.needsBackend && appConfig.backendPlatform ? appConfig.backendPlatform : "none";
|
|
8871
|
+
const row = getScaffoldRow(builder, backend);
|
|
8872
|
+
const templateDir = row.baseTemplate;
|
|
8810
8873
|
const firebaseProjectId = (appConfig?.firebaseProjectId ?? "").trim() || appName.toLowerCase().replace(/\s+/g, "-");
|
|
8811
8874
|
const firebaseRegion = appConfig?.firebaseRegion ?? "europe-west1";
|
|
8875
|
+
const backendPlatform = appConfig.backendPlatform ?? "firebase";
|
|
8876
|
+
const deployConfig = row.deployConfig;
|
|
8812
8877
|
const replacements = {
|
|
8813
8878
|
projectName: appName,
|
|
8814
8879
|
appName,
|
|
8815
8880
|
appShortName: appName.toUpperCase().replace(/-/g, " "),
|
|
8816
|
-
includeFunctions: Boolean(
|
|
8881
|
+
includeFunctions: Boolean(row.functionsTemplate),
|
|
8817
8882
|
needsCRUD: Boolean(appConfig.needsCRUD),
|
|
8818
8883
|
setupGithubActions: false,
|
|
8819
8884
|
appNames: [appName],
|
|
@@ -8823,8 +8888,13 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
8823
8888
|
monorepoRelativePath: "../../packages/tooling",
|
|
8824
8889
|
appTemplate,
|
|
8825
8890
|
isNextjs: appTemplate === "nextjs",
|
|
8891
|
+
isExpo: appTemplate === "expo",
|
|
8826
8892
|
YOUR_FIREBASE_PROJECT_ID: firebaseProjectId,
|
|
8827
|
-
YOUR_REGION: firebaseRegion
|
|
8893
|
+
YOUR_REGION: firebaseRegion,
|
|
8894
|
+
backendPlatform,
|
|
8895
|
+
isFirebase: backendPlatform === "firebase",
|
|
8896
|
+
isSupabase: backendPlatform === "supabase",
|
|
8897
|
+
isVercel: backendPlatform === "vercel"
|
|
8828
8898
|
};
|
|
8829
8899
|
const templateSourceDir = joinPath(templatesRoot, templateDir);
|
|
8830
8900
|
const templateFiles = await glob("**/*", {
|
|
@@ -8845,118 +8915,155 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
8845
8915
|
await replacePlaceholders(destPath, replacements);
|
|
8846
8916
|
}
|
|
8847
8917
|
}
|
|
8918
|
+
if (row.overlay) {
|
|
8919
|
+
const overlayDir = joinPath(templatesRoot, row.overlay);
|
|
8920
|
+
if (pathExists(overlayDir)) {
|
|
8921
|
+
const overlayFiles = await glob("**/*", {
|
|
8922
|
+
cwd: overlayDir,
|
|
8923
|
+
dot: true,
|
|
8924
|
+
onlyFiles: true
|
|
8925
|
+
});
|
|
8926
|
+
for (const file of overlayFiles) {
|
|
8927
|
+
if (file.startsWith("env.fragment")) continue;
|
|
8928
|
+
if (file === "vercel.headers.example") continue;
|
|
8929
|
+
if (file === "vercel.json.example") continue;
|
|
8930
|
+
if (file === "src/config/providers.ts.example") {
|
|
8931
|
+
const variantFile = `src/config/providers.${appTemplate}.ts.example`;
|
|
8932
|
+
if (overlayFiles.includes(variantFile)) continue;
|
|
8933
|
+
}
|
|
8934
|
+
const providersVariant = file.match(/^src\/config\/providers\.(\w+)\.ts\.example$/);
|
|
8935
|
+
if (providersVariant) {
|
|
8936
|
+
if (providersVariant[1] !== appTemplate) continue;
|
|
8937
|
+
const destPath2 = joinPath(appDir, "src/config/providers.ts");
|
|
8938
|
+
await ensureDir(getDirname(destPath2));
|
|
8939
|
+
await copy(joinPath(overlayDir, file), destPath2);
|
|
8940
|
+
if (await isTextFile(destPath2)) await replacePlaceholders(destPath2, replacements);
|
|
8941
|
+
continue;
|
|
8942
|
+
}
|
|
8943
|
+
const sourcePath = joinPath(overlayDir, file);
|
|
8944
|
+
let destFileName = file;
|
|
8945
|
+
if (destFileName.endsWith(".example")) {
|
|
8946
|
+
destFileName = destFileName.slice(0, -8);
|
|
8947
|
+
}
|
|
8948
|
+
const destPath = joinPath(appDir, destFileName);
|
|
8949
|
+
await ensureDir(getDirname(destPath));
|
|
8950
|
+
await copy(sourcePath, destPath);
|
|
8951
|
+
if (await isTextFile(destPath)) {
|
|
8952
|
+
await replacePlaceholders(destPath, replacements);
|
|
8953
|
+
}
|
|
8954
|
+
}
|
|
8955
|
+
const fragmentName = appTemplate === "nextjs" ? "env.fragment.nextjs.example" : appTemplate === "expo" ? "env.fragment.expo.example" : "env.fragment.example";
|
|
8956
|
+
const fragmentPath = joinPath(overlayDir, fragmentName);
|
|
8957
|
+
const envPath = joinPath(appDir, ".env");
|
|
8958
|
+
if (pathExists(fragmentPath) && pathExists(envPath)) {
|
|
8959
|
+
const baseEnv = readSync(envPath);
|
|
8960
|
+
const fragment = readSync(fragmentPath);
|
|
8961
|
+
await write(envPath, baseEnv + "\n" + fragment, { overwrite: true });
|
|
8962
|
+
}
|
|
8963
|
+
if (deployConfig === "vercel-supabase") {
|
|
8964
|
+
const vercelPath = joinPath(appDir, "vercel.json");
|
|
8965
|
+
const headersFragmentPath = joinPath(overlayDir, "vercel.headers.example");
|
|
8966
|
+
const fullVercelPath = joinPath(overlayDir, "vercel.json.example");
|
|
8967
|
+
if (pathExists(vercelPath) && pathExists(headersFragmentPath)) {
|
|
8968
|
+
const vercelJson = readSync(vercelPath, { format: "json" });
|
|
8969
|
+
const headersFragment = readSync(headersFragmentPath, { format: "json" });
|
|
8970
|
+
vercelJson.headers = [...vercelJson.headers ?? [], ...headersFragment];
|
|
8971
|
+
await write(vercelPath, vercelJson, { format: "json", overwrite: true });
|
|
8972
|
+
} else if (pathExists(fullVercelPath)) {
|
|
8973
|
+
await copy(fullVercelPath, vercelPath);
|
|
8974
|
+
if (await isTextFile(vercelPath)) await replacePlaceholders(vercelPath, replacements);
|
|
8975
|
+
}
|
|
8976
|
+
}
|
|
8977
|
+
}
|
|
8978
|
+
}
|
|
8848
8979
|
const executionMode = detectExecutionMode();
|
|
8849
8980
|
const templateName = appTemplate === "demo" ? "demo" : executionMode === "development" ? `dev-${appTemplate}` : `consumer-${appTemplate}`;
|
|
8850
8981
|
const packageJson = generatePackageJson(templateName, executionMode, {
|
|
8851
8982
|
appName,
|
|
8852
8983
|
template: appTemplate === "demo" ? "vite" : appTemplate,
|
|
8853
|
-
includeFunctions: Boolean(
|
|
8984
|
+
includeFunctions: Boolean(row.functionsTemplate),
|
|
8985
|
+
platform: appTemplate === "demo" ? void 0 : backendPlatform
|
|
8854
8986
|
});
|
|
8855
8987
|
const packageJsonPath = joinPath(appDir, "package.json");
|
|
8856
8988
|
await write(packageJsonPath, packageJson, {
|
|
8857
8989
|
format: "json",
|
|
8858
8990
|
overwrite: true
|
|
8859
8991
|
});
|
|
8860
|
-
if (
|
|
8861
|
-
const platform = appConfig.backendPlatform;
|
|
8992
|
+
if (row.functionsTemplate) {
|
|
8862
8993
|
const functionsRootDir = joinPath(appDir, "functions");
|
|
8863
|
-
const functionsTemplateName =
|
|
8864
|
-
const
|
|
8865
|
-
|
|
8866
|
-
|
|
8867
|
-
|
|
8868
|
-
|
|
8869
|
-
|
|
8870
|
-
|
|
8871
|
-
|
|
8872
|
-
|
|
8873
|
-
|
|
8874
|
-
|
|
8875
|
-
|
|
8876
|
-
|
|
8877
|
-
|
|
8878
|
-
|
|
8879
|
-
templatesRoot,
|
|
8880
|
-
|
|
8881
|
-
|
|
8882
|
-
|
|
8883
|
-
|
|
8884
|
-
|
|
8885
|
-
|
|
8886
|
-
|
|
8887
|
-
|
|
8888
|
-
|
|
8889
|
-
|
|
8890
|
-
|
|
8891
|
-
|
|
8892
|
-
|
|
8893
|
-
|
|
8894
|
-
|
|
8895
|
-
|
|
8896
|
-
|
|
8897
|
-
|
|
8898
|
-
|
|
8899
|
-
|
|
8900
|
-
|
|
8901
|
-
await replacePlaceholders(destPath, {
|
|
8902
|
-
...replacements,
|
|
8903
|
-
APP_NAME: appName
|
|
8904
|
-
});
|
|
8994
|
+
const functionsTemplateName = row.functionsTemplate;
|
|
8995
|
+
const functionsTemplateExists = pathExists(joinPath(templatesRoot, functionsTemplateName));
|
|
8996
|
+
if (!functionsTemplateExists) {
|
|
8997
|
+
log.warn(`Functions template "${functionsTemplateName}" not found \u2014 skipping functions scaffolding.`);
|
|
8998
|
+
} else {
|
|
8999
|
+
const functionsPackageJson = generatePackageJson(
|
|
9000
|
+
functionsTemplateName,
|
|
9001
|
+
executionMode,
|
|
9002
|
+
{ appName, platform: row.functionsTemplate.replace("functions-", "") }
|
|
9003
|
+
);
|
|
9004
|
+
const packageJsonPath2 = joinPath(functionsRootDir, "package.json");
|
|
9005
|
+
await ensureDir(functionsRootDir);
|
|
9006
|
+
await write(packageJsonPath2, functionsPackageJson, {
|
|
9007
|
+
format: "json",
|
|
9008
|
+
overwrite: true
|
|
9009
|
+
});
|
|
9010
|
+
const templateDir2 = joinPath(templatesRoot, functionsTemplateName);
|
|
9011
|
+
const templateFiles2 = await glob("**/*", {
|
|
9012
|
+
cwd: templateDir2,
|
|
9013
|
+
dot: true,
|
|
9014
|
+
onlyFiles: true
|
|
9015
|
+
});
|
|
9016
|
+
for (const file of templateFiles2) {
|
|
9017
|
+
if (file === "package.json.example") continue;
|
|
9018
|
+
const sourcePath = joinPath(templateDir2, file);
|
|
9019
|
+
let destFileName = file;
|
|
9020
|
+
if (destFileName.endsWith(".example")) {
|
|
9021
|
+
destFileName = destFileName.slice(0, -8);
|
|
9022
|
+
}
|
|
9023
|
+
const destPath = joinPath(functionsRootDir, destFileName);
|
|
9024
|
+
await ensureDir(getDirname(destPath));
|
|
9025
|
+
await copy(sourcePath, destPath);
|
|
9026
|
+
if (await isTextFile(destPath)) {
|
|
9027
|
+
await replacePlaceholders(destPath, {
|
|
9028
|
+
...replacements,
|
|
9029
|
+
APP_NAME: appName
|
|
9030
|
+
});
|
|
9031
|
+
}
|
|
8905
9032
|
}
|
|
8906
9033
|
}
|
|
8907
9034
|
}
|
|
8908
9035
|
const deploymentTemplateDir = joinPath(templatesRoot, "root-consumer");
|
|
8909
|
-
|
|
8910
|
-
deploymentTemplateDir,
|
|
8911
|
-
|
|
8912
|
-
|
|
8913
|
-
|
|
8914
|
-
|
|
8915
|
-
|
|
8916
|
-
|
|
8917
|
-
|
|
9036
|
+
if (deployConfig === "firebase") {
|
|
9037
|
+
const firebaseJsonSource = joinPath(deploymentTemplateDir, "firebase.json.example");
|
|
9038
|
+
if (pathExists(firebaseJsonSource)) {
|
|
9039
|
+
await copy(firebaseJsonSource, joinPath(appDir, "firebase.json"));
|
|
9040
|
+
const firebaseJsonDest = joinPath(appDir, "firebase.json");
|
|
9041
|
+
if (await isTextFile(firebaseJsonDest)) await replacePlaceholders(firebaseJsonDest, replacements);
|
|
9042
|
+
}
|
|
9043
|
+
const firebasercSource = joinPath(deploymentTemplateDir, ".firebaserc.example");
|
|
9044
|
+
if (pathExists(firebasercSource)) {
|
|
9045
|
+
await copy(firebasercSource, joinPath(appDir, ".firebaserc"));
|
|
9046
|
+
const firebasercDest = joinPath(appDir, ".firebaserc");
|
|
9047
|
+
if (await isTextFile(firebasercDest)) await replacePlaceholders(firebasercDest, replacements);
|
|
9048
|
+
}
|
|
9049
|
+
if (row.functionsTemplate === "functions-firebase") {
|
|
9050
|
+
for (const example of ["firestore.rules.example", "firestore.indexes.json.example", "storage.rules.example"]) {
|
|
9051
|
+
const src = joinPath(deploymentTemplateDir, example);
|
|
9052
|
+
if (pathExists(src)) {
|
|
9053
|
+
await copy(src, joinPath(appDir, example.replace(".example", "")));
|
|
9054
|
+
}
|
|
9055
|
+
}
|
|
8918
9056
|
}
|
|
8919
9057
|
}
|
|
8920
|
-
|
|
8921
|
-
deploymentTemplateDir,
|
|
8922
|
-
".firebaserc.example"
|
|
8923
|
-
);
|
|
8924
|
-
if (pathExists(firebasercSource)) {
|
|
8925
|
-
const firebasercDest = joinPath(appDir, ".firebaserc");
|
|
8926
|
-
await copy(firebasercSource, firebasercDest);
|
|
8927
|
-
if (await isTextFile(firebasercDest)) {
|
|
8928
|
-
await replacePlaceholders(firebasercDest, replacements);
|
|
8929
|
-
}
|
|
8930
|
-
}
|
|
8931
|
-
if (appConfig.needsBackend && appConfig.backendPlatform === "firebase") {
|
|
8932
|
-
const rulesFiles = [
|
|
8933
|
-
"firestore.rules.example",
|
|
8934
|
-
"firestore.indexes.json.example",
|
|
8935
|
-
"storage.rules.example"
|
|
8936
|
-
];
|
|
8937
|
-
for (const example of rulesFiles) {
|
|
8938
|
-
const src = joinPath(deploymentTemplateDir, example);
|
|
8939
|
-
if (pathExists(src)) {
|
|
8940
|
-
const destName = example.replace(".example", "");
|
|
8941
|
-
const dest = joinPath(appDir, destName);
|
|
8942
|
-
await copy(src, dest);
|
|
8943
|
-
}
|
|
8944
|
-
}
|
|
8945
|
-
}
|
|
8946
|
-
if (appTemplate === "nextjs" || appConfig.needsBackend && appConfig.backendPlatform === "vercel") {
|
|
8947
|
-
const vercelJsonSource = joinPath(
|
|
8948
|
-
deploymentTemplateDir,
|
|
8949
|
-
"vercel.json.example"
|
|
8950
|
-
);
|
|
9058
|
+
if (deployConfig === "vercel-vercel") {
|
|
9059
|
+
const vercelJsonSource = joinPath(deploymentTemplateDir, "vercel.json.example");
|
|
8951
9060
|
if (pathExists(vercelJsonSource)) {
|
|
9061
|
+
await copy(vercelJsonSource, joinPath(appDir, "vercel.json"));
|
|
8952
9062
|
const vercelJsonDest = joinPath(appDir, "vercel.json");
|
|
8953
|
-
await
|
|
8954
|
-
if (await isTextFile(vercelJsonDest)) {
|
|
8955
|
-
await replacePlaceholders(vercelJsonDest, replacements);
|
|
8956
|
-
}
|
|
9063
|
+
if (await isTextFile(vercelJsonDest)) await replacePlaceholders(vercelJsonDest, replacements);
|
|
8957
9064
|
}
|
|
8958
9065
|
}
|
|
8959
|
-
const backendInfo =
|
|
9066
|
+
const backendInfo = row.functionsTemplate ? ` with ${row.functionsTemplate.replace("functions-", "")} functions` : "";
|
|
8960
9067
|
s.stop(`Created ${appName}${backendInfo}`);
|
|
8961
9068
|
const rootPackageJsonPath = joinPath(workspaceRoot, "package.json");
|
|
8962
9069
|
if (pathExists(rootPackageJsonPath)) {
|
|
@@ -8968,7 +9075,7 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
8968
9075
|
}
|
|
8969
9076
|
if (isInteractive) {
|
|
8970
9077
|
Se("\u{1F389} App created successfully!");
|
|
8971
|
-
const firebaseStep =
|
|
9078
|
+
const firebaseStep = row.functionsTemplate === "functions-firebase" ? `2. Set Firebase project: cd apps/${appName} && firebase use --add (or edit .firebaserc)
|
|
8972
9079
|
3. bun install
|
|
8973
9080
|
4. bun run dev` : `2. bun install
|
|
8974
9081
|
3. bun run dev`;
|
|
@@ -8985,8 +9092,8 @@ Happy coding!`,
|
|
|
8985
9092
|
}
|
|
8986
9093
|
async function main(options) {
|
|
8987
9094
|
try {
|
|
8988
|
-
const
|
|
8989
|
-
if (
|
|
9095
|
+
const hasExplicitFlags = options?.builder !== void 0 || options?.functions !== void 0;
|
|
9096
|
+
if (hasExplicitFlags && options?.name) {
|
|
8990
9097
|
const appName = options.name;
|
|
8991
9098
|
const builder = options.builder || "vite";
|
|
8992
9099
|
const includeFunctions = options.functions ?? false;
|
|
@@ -9001,7 +9108,7 @@ async function main(options) {
|
|
|
9001
9108
|
);
|
|
9002
9109
|
}
|
|
9003
9110
|
const appConfig = {
|
|
9004
|
-
template: builder === "next" ? "nextjs" : "vite",
|
|
9111
|
+
template: builder === "next" ? "nextjs" : builder === "expo" ? "expo" : "vite",
|
|
9005
9112
|
needsBackend: includeFunctions,
|
|
9006
9113
|
backendPlatform: includeFunctions ? "firebase" : void 0,
|
|
9007
9114
|
needsCRUD: true,
|
|
@@ -9014,7 +9121,7 @@ async function main(options) {
|
|
|
9014
9121
|
};
|
|
9015
9122
|
await createApp(appName, appConfig);
|
|
9016
9123
|
} else {
|
|
9017
|
-
await createApp();
|
|
9124
|
+
await createApp(options?.name);
|
|
9018
9125
|
}
|
|
9019
9126
|
} catch (error2) {
|
|
9020
9127
|
log.error("\n\u274C Error creating app:", error2);
|