@donotdev/cli 0.0.18 → 0.0.19
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 +55 -156
- package/dist/bin/commands/coach.js +8177 -0
- package/dist/bin/commands/create-app.js +5 -5
- package/dist/bin/commands/create-project.js +10 -7
- package/dist/bin/commands/deploy.js +81 -59
- package/dist/bin/commands/doctor.js +243 -698
- package/dist/bin/commands/emu.js +2 -2
- package/dist/bin/commands/format.js +4 -1
- package/dist/bin/commands/get-demo.js +8351 -0
- package/dist/bin/commands/make-admin.js +773 -152
- package/dist/bin/commands/setup.js +519 -1711
- package/dist/bin/commands/staging.js +17852 -0
- package/dist/bin/commands/sync-secrets.js +2 -11
- package/dist/bin/commands/type-check.js +7733 -1713
- package/dist/bin/dndev.js +913 -185
- package/dist/bin/donotdev.js +913 -185
- package/dist/index.js +96 -65
- package/package.json +1 -1
- package/templates/app-demo/index.html.example +147 -10
- package/templates/app-demo/src/App.tsx.example +7 -13
- package/templates/app-demo/src/config/app.ts.example +12 -48
- package/templates/app-demo/src/entities/product.ts.example +38 -0
- package/templates/app-demo/src/globals.css.example +5 -1
- package/templates/app-demo/src/main.tsx.example +13 -7
- package/templates/app-demo/src/pages/ChangelogPage.tsx.example +14 -0
- package/templates/app-demo/src/pages/DashboardPage.tsx.example +15 -0
- package/templates/app-demo/src/pages/HomePage.tsx.example +3 -77
- package/templates/app-demo/src/pages/PricingPage.tsx.example +14 -0
- package/templates/app-demo/src/pages/ProductsPage.tsx.example +17 -0
- package/templates/app-demo/src/pages/ProfilePage.tsx.example +16 -0
- package/templates/app-demo/src/pages/SettingsPage.tsx.example +15 -0
- package/templates/app-demo/src/pages/ShowcaseDetailPage.tsx.example +112 -0
- package/templates/app-demo/src/pages/ShowcasePage.tsx.example +91 -0
- package/templates/app-demo/src/pages/legal/LegalPage.tsx.example +14 -0
- package/templates/app-demo/src/pages/legal/PrivacyPage.tsx.example +14 -0
- package/templates/app-demo/src/pages/legal/TermsPage.tsx.example +14 -0
- package/templates/app-demo/tsconfig.json.example +1 -1
- package/templates/app-demo/vite.config.ts.example +23 -48
- package/templates/app-expo/README.md.example +1 -1
- package/templates/app-expo/app/index.tsx.example +1 -1
- package/templates/app-vite/src/pages/HomePage.tsx.example +8 -10
- 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 +1 -1
- package/templates/overlay-supabase/env.fragment.expo.example +1 -1
- package/templates/overlay-supabase/env.fragment.nextjs.example +1 -1
- 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 +4 -3
- package/templates/root-consumer/guides/dndev/AGENT_START_HERE.md.example +21 -6
- package/templates/root-consumer/guides/dndev/COMPONENTS_ADV.md.example +16 -179
- package/templates/root-consumer/guides/dndev/ENV_SETUP.md.example +19 -21
- package/templates/root-consumer/guides/dndev/GOTCHAS.md.example +14 -3
- package/templates/root-consumer/guides/dndev/INDEX.md.example +2 -2
- package/templates/root-consumer/guides/dndev/SETUP_APP_CONFIG.md.example +3 -3
- package/templates/root-consumer/guides/dndev/SETUP_BLOG.md.example +19 -2
- package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +35 -1
- package/templates/root-consumer/guides/dndev/SETUP_FIREBASE.md.example +17 -12
- package/templates/root-consumer/guides/dndev/SETUP_LAYOUTS.md.example +32 -0
- package/templates/root-consumer/guides/dndev/SETUP_OAUTH_PROVIDERS.md.example +1 -1
- package/templates/root-consumer/guides/dndev/SETUP_PAGES.md.example +19 -15
- package/templates/root-consumer/guides/dndev/SETUP_STRIPE.md.example +2 -2
- package/templates/root-consumer/guides/dndev/SETUP_SUPABASE.md.example +17 -12
- package/templates/root-consumer/guides/dndev/SETUP_VERCEL.md.example +37 -16
- package/templates/root-consumer/guides/dndev/USE_ROUTING.md.example +18 -18
- package/templates/root-consumer/guides/dndev/essences_reference.css.example +119 -2
- package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +14 -0
- package/templates/root-consumer/guides/wai-way/blueprints/2_entities.md.example +6 -0
- package/templates/root-consumer/guides/wai-way/blueprints/3_compose.md.example +14 -0
- package/templates/root-consumer/guides/wai-way/entity_patterns.md.example +4 -5
- package/templates/root-consumer/guides/wai-way/page_patterns.md.example +2 -2
- package/dist/bin/commands/agent-setup.d.ts +0 -6
- package/dist/bin/commands/agent-setup.d.ts.map +0 -1
- package/dist/bin/commands/agent-setup.js.map +0 -1
- package/dist/bin/commands/build.d.ts +0 -11
- package/dist/bin/commands/build.d.ts.map +0 -1
- package/dist/bin/commands/build.js.map +0 -1
- package/dist/bin/commands/bump.d.ts +0 -11
- package/dist/bin/commands/bump.d.ts.map +0 -1
- package/dist/bin/commands/bump.js.map +0 -1
- package/dist/bin/commands/cacheout.d.ts +0 -11
- package/dist/bin/commands/cacheout.d.ts.map +0 -1
- package/dist/bin/commands/cacheout.js.map +0 -1
- package/dist/bin/commands/create-app.d.ts +0 -11
- package/dist/bin/commands/create-app.d.ts.map +0 -1
- package/dist/bin/commands/create-app.js.map +0 -1
- package/dist/bin/commands/create-project.d.ts +0 -11
- package/dist/bin/commands/create-project.d.ts.map +0 -1
- package/dist/bin/commands/create-project.js.map +0 -1
- package/dist/bin/commands/deploy.d.ts +0 -11
- package/dist/bin/commands/deploy.d.ts.map +0 -1
- package/dist/bin/commands/deploy.js.map +0 -1
- package/dist/bin/commands/dev.d.ts +0 -11
- package/dist/bin/commands/dev.d.ts.map +0 -1
- package/dist/bin/commands/dev.js.map +0 -1
- package/dist/bin/commands/doctor.d.ts +0 -6
- package/dist/bin/commands/doctor.d.ts.map +0 -1
- package/dist/bin/commands/doctor.js.map +0 -1
- package/dist/bin/commands/emu.d.ts +0 -11
- package/dist/bin/commands/emu.d.ts.map +0 -1
- package/dist/bin/commands/emu.js.map +0 -1
- package/dist/bin/commands/format.d.ts +0 -11
- package/dist/bin/commands/format.d.ts.map +0 -1
- package/dist/bin/commands/format.js.map +0 -1
- package/dist/bin/commands/make-admin.d.ts +0 -11
- package/dist/bin/commands/make-admin.d.ts.map +0 -1
- package/dist/bin/commands/make-admin.js.map +0 -1
- package/dist/bin/commands/preview.d.ts +0 -11
- package/dist/bin/commands/preview.d.ts.map +0 -1
- package/dist/bin/commands/preview.js.map +0 -1
- package/dist/bin/commands/setup.d.ts +0 -6
- package/dist/bin/commands/setup.d.ts.map +0 -1
- package/dist/bin/commands/setup.js.map +0 -1
- package/dist/bin/commands/sync-secrets.d.ts +0 -11
- package/dist/bin/commands/sync-secrets.d.ts.map +0 -1
- package/dist/bin/commands/sync-secrets.js.map +0 -1
- package/dist/bin/commands/type-check.d.ts +0 -14
- package/dist/bin/commands/type-check.d.ts.map +0 -1
- package/dist/bin/commands/type-check.js.map +0 -1
- package/dist/bin/commands/wai.d.ts +0 -11
- package/dist/bin/commands/wai.d.ts.map +0 -1
- package/dist/bin/commands/wai.js.map +0 -1
- package/dist/index.d.ts +0 -8
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/templates/app-demo/src/components/ThemeToggle.tsx.example +0 -48
- package/templates/app-demo/src/pages/DetailPage.tsx.example +0 -103
- package/templates/app-demo/src/pages/FullPage.tsx.example +0 -142
- package/templates/app-demo/src/pages/components/DemoLayout.tsx.example +0 -266
- package/templates/app-demo/src/pages/components/LayoutRoute.tsx.example +0 -20
package/dist/index.js
CHANGED
|
@@ -8859,21 +8859,21 @@ function getCLIInstallInstructions(tool) {
|
|
|
8859
8859
|
]
|
|
8860
8860
|
},
|
|
8861
8861
|
[CLI_TOOLS.YARN]: {
|
|
8862
|
-
win32: ["
|
|
8863
|
-
darwin: ["
|
|
8864
|
-
linux: ["
|
|
8862
|
+
win32: ["bun install -g yarn", "Or: choco install yarn"],
|
|
8863
|
+
darwin: ["bun install -g yarn", "Or: brew install yarn"],
|
|
8864
|
+
linux: ["bun install -g yarn", "Or check your package manager"]
|
|
8865
8865
|
},
|
|
8866
8866
|
[CLI_TOOLS.FIREBASE]: {
|
|
8867
8867
|
win32: [
|
|
8868
|
-
"
|
|
8868
|
+
"bun install -g firebase-tools",
|
|
8869
8869
|
"Or download standalone binary: https://firebase.google.com/docs/cli#windows-standalone-binary"
|
|
8870
8870
|
],
|
|
8871
8871
|
darwin: [
|
|
8872
|
-
"
|
|
8872
|
+
"bun install -g firebase-tools",
|
|
8873
8873
|
"Or: brew install firebase-cli"
|
|
8874
8874
|
],
|
|
8875
8875
|
linux: [
|
|
8876
|
-
"
|
|
8876
|
+
"bun install -g firebase-tools",
|
|
8877
8877
|
"Or check your package manager (dnf, apt, pacman, etc.)"
|
|
8878
8878
|
]
|
|
8879
8879
|
},
|
|
@@ -8890,25 +8890,25 @@ function getCLIInstallInstructions(tool) {
|
|
|
8890
8890
|
]
|
|
8891
8891
|
},
|
|
8892
8892
|
[CLI_TOOLS.VERCEL]: {
|
|
8893
|
-
win32: ["
|
|
8893
|
+
win32: ["bun install -g vercel", "Or: bunx vercel (no install)"],
|
|
8894
8894
|
darwin: [
|
|
8895
|
-
"
|
|
8895
|
+
"bun install -g vercel",
|
|
8896
8896
|
"Or: brew install vercel",
|
|
8897
|
-
"Or:
|
|
8897
|
+
"Or: bunx vercel"
|
|
8898
8898
|
],
|
|
8899
|
-
linux: ["
|
|
8899
|
+
linux: ["bun install -g vercel", "Or: bunx vercel"]
|
|
8900
8900
|
},
|
|
8901
8901
|
[CLI_TOOLS.SENTRY_CLI]: {
|
|
8902
8902
|
win32: [
|
|
8903
|
-
"
|
|
8903
|
+
"bun install -g @sentry/cli",
|
|
8904
8904
|
"Or download from: https://github.com/getsentry/sentry-cli/releases"
|
|
8905
8905
|
],
|
|
8906
8906
|
darwin: [
|
|
8907
|
-
"
|
|
8907
|
+
"bun install -g @sentry/cli",
|
|
8908
8908
|
"Or: brew install getsentry/tools/sentry-cli"
|
|
8909
8909
|
],
|
|
8910
8910
|
linux: [
|
|
8911
|
-
"
|
|
8911
|
+
"bun install -g @sentry/cli",
|
|
8912
8912
|
"Or: curl -sL https://sentry.io/get-cli/ | bash"
|
|
8913
8913
|
]
|
|
8914
8914
|
},
|
|
@@ -8937,9 +8937,9 @@ function getCLIInstallInstructions(tool) {
|
|
|
8937
8937
|
]
|
|
8938
8938
|
},
|
|
8939
8939
|
[CLI_TOOLS.TSX]: {
|
|
8940
|
-
win32: ["
|
|
8941
|
-
darwin: ["
|
|
8942
|
-
linux: ["
|
|
8940
|
+
win32: ["bun install -g tsx"],
|
|
8941
|
+
darwin: ["bun install -g tsx"],
|
|
8942
|
+
linux: ["bun install -g tsx"]
|
|
8943
8943
|
}
|
|
8944
8944
|
};
|
|
8945
8945
|
const platformInstructions = instructions[tool]?.[platform6] || instructions[tool]?.linux || [];
|
|
@@ -9034,14 +9034,27 @@ function readEnvVar(filePath, varName) {
|
|
|
9034
9034
|
}
|
|
9035
9035
|
return null;
|
|
9036
9036
|
}
|
|
9037
|
-
function
|
|
9038
|
-
if (process.env
|
|
9039
|
-
const
|
|
9040
|
-
if (fromEnv) return fromEnv;
|
|
9041
|
-
const fromLocal = readEnvVar(joinPath(appDir, ".env.local"), "VERCEL_TOKEN");
|
|
9037
|
+
function resolveVercelVar(appDir, varName) {
|
|
9038
|
+
if (process.env[varName]) return process.env[varName];
|
|
9039
|
+
const fromLocal = readEnvVar(joinPath(appDir, ".env.local"), varName);
|
|
9042
9040
|
if (fromLocal) return fromLocal;
|
|
9041
|
+
const fromEnv = readEnvVar(joinPath(appDir, ".env"), varName);
|
|
9042
|
+
if (fromEnv) return fromEnv;
|
|
9043
9043
|
return null;
|
|
9044
9044
|
}
|
|
9045
|
+
function resolveVercelCredentials(appDir) {
|
|
9046
|
+
const token = resolveVercelVar(appDir, "VERCEL_TOKEN");
|
|
9047
|
+
const orgId = resolveVercelVar(appDir, "VERCEL_ORG_ID");
|
|
9048
|
+
const projectId = resolveVercelVar(appDir, "VERCEL_PROJECT_ID");
|
|
9049
|
+
const missing = [];
|
|
9050
|
+
if (!token) missing.push("VERCEL_TOKEN");
|
|
9051
|
+
if (!orgId) missing.push("VERCEL_ORG_ID");
|
|
9052
|
+
if (!projectId) missing.push("VERCEL_PROJECT_ID");
|
|
9053
|
+
if (missing.length > 0) return { missing };
|
|
9054
|
+
return {
|
|
9055
|
+
credentials: { token, orgId, projectId }
|
|
9056
|
+
};
|
|
9057
|
+
}
|
|
9045
9058
|
var init_vercel_token = __esm({
|
|
9046
9059
|
"packages/tooling/src/cli/setup/vercel-token.ts"() {
|
|
9047
9060
|
"use strict";
|
|
@@ -16621,10 +16634,7 @@ async function setFirebaseSecret(key, value, projectId, dryRun = false, cwd) {
|
|
|
16621
16634
|
}
|
|
16622
16635
|
try {
|
|
16623
16636
|
log.info(`Setting Firebase secret: ${key} (project: ${finalProjectId})`);
|
|
16624
|
-
const
|
|
16625
|
-
await ensureDir(tempDir);
|
|
16626
|
-
const tempFile = joinPath(tempDir, `secret-${key}-${Date.now()}.txt`);
|
|
16627
|
-
await write(tempFile, value);
|
|
16637
|
+
const tempFile = "";
|
|
16628
16638
|
try {
|
|
16629
16639
|
const args = ["functions:secrets:set", key, "--project", finalProjectId];
|
|
16630
16640
|
const firebaseCmd = process.platform === "win32" ? "firebase.cmd" : "firebase";
|
|
@@ -16699,9 +16709,6 @@ ${errorOutput}`
|
|
|
16699
16709
|
}
|
|
16700
16710
|
log.success(`Firebase secret ${key} set successfully`);
|
|
16701
16711
|
} finally {
|
|
16702
|
-
if (pathExists(tempFile)) {
|
|
16703
|
-
await remove(tempFile);
|
|
16704
|
-
}
|
|
16705
16712
|
}
|
|
16706
16713
|
} catch (err) {
|
|
16707
16714
|
log.error(`Failed to set Firebase secret ${key}:`, err);
|
|
@@ -17934,7 +17941,7 @@ async function startSupabase(app, _projectRoot) {
|
|
|
17934
17941
|
execSync5("supabase --version", { stdio: "pipe" });
|
|
17935
17942
|
} catch {
|
|
17936
17943
|
log.error("Supabase CLI not found. Install it:");
|
|
17937
|
-
log.error("
|
|
17944
|
+
log.error(" bun install -g supabase\n");
|
|
17938
17945
|
return 1;
|
|
17939
17946
|
}
|
|
17940
17947
|
const isWindows = platform3() === "win32";
|
|
@@ -18004,7 +18011,7 @@ async function startVercel(app, _projectRoot) {
|
|
|
18004
18011
|
execSync6("vercel --version", { stdio: "pipe" });
|
|
18005
18012
|
} catch {
|
|
18006
18013
|
log.error("Vercel CLI not found. Install it:");
|
|
18007
|
-
log.error("
|
|
18014
|
+
log.error(" bun install -g vercel\n");
|
|
18008
18015
|
return 1;
|
|
18009
18016
|
}
|
|
18010
18017
|
const isWindows = platform4() === "win32";
|
|
@@ -18782,33 +18789,39 @@ init_cli_output();
|
|
|
18782
18789
|
init_vercel_token();
|
|
18783
18790
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
18784
18791
|
async function deployVercelFrontend(appDir, _config) {
|
|
18785
|
-
const
|
|
18786
|
-
|
|
18787
|
-
|
|
18788
|
-
|
|
18789
|
-
|
|
18790
|
-
|
|
18791
|
-
const args = ["vercel", "--prod", "--yes"];
|
|
18792
|
-
if (token) {
|
|
18793
|
-
args.push("--token", token);
|
|
18792
|
+
const result = resolveVercelCredentials(appDir);
|
|
18793
|
+
if (result.missing) {
|
|
18794
|
+
throw new Error(
|
|
18795
|
+
`Missing Vercel credentials in .env.local: ${result.missing.join(", ")}
|
|
18796
|
+
Add them to apps/<app>/.env.local \u2014 see guides/dndev/SETUP_VERCEL.md`
|
|
18797
|
+
);
|
|
18794
18798
|
}
|
|
18795
|
-
|
|
18796
|
-
|
|
18799
|
+
const { token, orgId, projectId } = result.credentials;
|
|
18800
|
+
log.debug("Using Vercel credentials from .env (token-based auth)");
|
|
18801
|
+
log.info("Deploying to Vercel...");
|
|
18802
|
+
const deployResult = spawnSync6(
|
|
18803
|
+
"bunx",
|
|
18804
|
+
["vercel", "deploy", "--prod", "--yes", "--token", token],
|
|
18805
|
+
{
|
|
18797
18806
|
cwd: appDir,
|
|
18798
|
-
|
|
18799
|
-
|
|
18800
|
-
|
|
18801
|
-
|
|
18802
|
-
|
|
18803
|
-
|
|
18804
|
-
|
|
18805
|
-
|
|
18806
|
-
);
|
|
18807
|
+
// stdout piped to capture deployment URL, stderr inherits for progress
|
|
18808
|
+
stdio: ["inherit", "pipe", "inherit"],
|
|
18809
|
+
encoding: "utf-8",
|
|
18810
|
+
env: {
|
|
18811
|
+
...process.env,
|
|
18812
|
+
VERCEL_ORG_ID: orgId,
|
|
18813
|
+
VERCEL_PROJECT_ID: projectId
|
|
18814
|
+
}
|
|
18807
18815
|
}
|
|
18808
|
-
|
|
18809
|
-
|
|
18810
|
-
|
|
18811
|
-
|
|
18816
|
+
);
|
|
18817
|
+
if (deployResult.status !== 0) {
|
|
18818
|
+
throw new Error(`vercel deploy exited with code ${deployResult.status}`);
|
|
18819
|
+
}
|
|
18820
|
+
const deployUrl = deployResult.stdout?.trim();
|
|
18821
|
+
if (deployUrl) {
|
|
18822
|
+
log.success(`Production: ${deployUrl}`);
|
|
18823
|
+
} else {
|
|
18824
|
+
log.success("Frontend deployed to Vercel");
|
|
18812
18825
|
}
|
|
18813
18826
|
}
|
|
18814
18827
|
|
|
@@ -19170,7 +19183,7 @@ async function deployFunctions(appDir, serviceAccountPath, projectId, config) {
|
|
|
19170
19183
|
|
|
19171
19184
|
To fix this, run:
|
|
19172
19185
|
cd ${functionsDir}
|
|
19173
|
-
|
|
19186
|
+
bun install --production`,
|
|
19174
19187
|
"file-not-found",
|
|
19175
19188
|
{ context: { missingPackages, functionsDir } }
|
|
19176
19189
|
);
|
|
@@ -19535,7 +19548,19 @@ function detectProvider(appDir) {
|
|
|
19535
19548
|
const supabaseFunctionsDir = joinPath(supabaseDir, "functions");
|
|
19536
19549
|
const supabaseMigrationsDir = joinPath(supabaseDir, "migrations");
|
|
19537
19550
|
const hasFirebase = pathExists(firebaseJsonPath);
|
|
19538
|
-
|
|
19551
|
+
let hasSupabase = pathExists(supabaseDir) || pathExists(supabaseConfigPath);
|
|
19552
|
+
if (!hasSupabase) {
|
|
19553
|
+
try {
|
|
19554
|
+
const envPath = joinPath(appDir, ".env");
|
|
19555
|
+
if (pathExists(envPath)) {
|
|
19556
|
+
const envContent = readSync(envPath);
|
|
19557
|
+
if (envContent.match(/VITE_SUPABASE_URL=.+/)) {
|
|
19558
|
+
hasSupabase = true;
|
|
19559
|
+
}
|
|
19560
|
+
}
|
|
19561
|
+
} catch {
|
|
19562
|
+
}
|
|
19563
|
+
}
|
|
19539
19564
|
let provider = "unknown";
|
|
19540
19565
|
if (hasFirebase && hasSupabase) {
|
|
19541
19566
|
provider = "both";
|
|
@@ -19899,7 +19924,7 @@ async function main6(options = {}) {
|
|
|
19899
19924
|
if (shouldDeployVercelFrontend) {
|
|
19900
19925
|
requireCLI(
|
|
19901
19926
|
CLI_TOOLS.VERCEL,
|
|
19902
|
-
"Vercel CLI is required to deploy the frontend.\nInstall:
|
|
19927
|
+
"Vercel CLI is required to deploy the frontend.\nInstall: bun install -g vercel"
|
|
19903
19928
|
);
|
|
19904
19929
|
}
|
|
19905
19930
|
if (shouldDeployFirebaseFrontend && serviceAccountPath && config.project) {
|
|
@@ -20014,10 +20039,10 @@ function generateScripts(templateName, options) {
|
|
|
20014
20039
|
scripts.lint = "eslint .";
|
|
20015
20040
|
scripts["type-check"] = "tsc --noEmit";
|
|
20016
20041
|
} else if (templateName === "consumer-root") {
|
|
20017
|
-
scripts.dev = "
|
|
20042
|
+
scripts.dev = "dndev dev";
|
|
20018
20043
|
scripts.build = "turbo run build";
|
|
20019
20044
|
scripts.lint = "turbo run lint";
|
|
20020
|
-
scripts["type-check"] = "
|
|
20045
|
+
scripts["type-check"] = "dndev tc";
|
|
20021
20046
|
} else if (templateName.includes("functions")) {
|
|
20022
20047
|
scripts.build = "node build.mjs";
|
|
20023
20048
|
scripts["build:tsc"] = "tsc";
|
|
@@ -20028,9 +20053,9 @@ function generateScripts(templateName, options) {
|
|
|
20028
20053
|
scripts.dev = "vercel dev";
|
|
20029
20054
|
}
|
|
20030
20055
|
} else if (templateName === "demo") {
|
|
20031
|
-
scripts.dev = "
|
|
20032
|
-
scripts.build = "tsc --noEmit &&
|
|
20033
|
-
scripts.preview = "
|
|
20056
|
+
scripts.dev = "vite";
|
|
20057
|
+
scripts.build = "tsc --noEmit && vite build --mode production";
|
|
20058
|
+
scripts.preview = "vite preview";
|
|
20034
20059
|
scripts["type-check"] = "tsc --noEmit";
|
|
20035
20060
|
} else if (templateName === "entities") {
|
|
20036
20061
|
}
|
|
@@ -20810,7 +20835,8 @@ async function main9(options) {
|
|
|
20810
20835
|
Me(`Configuring "${trimmedName}"...`, "\u2699\uFE0F");
|
|
20811
20836
|
const config = await collectAppConfig(trimmedName);
|
|
20812
20837
|
appConfigs[trimmedName] = config;
|
|
20813
|
-
if (config.backend !== "none" || config.functions !== "none")
|
|
20838
|
+
if (config.backend !== "none" || config.functions !== "none")
|
|
20839
|
+
anyAppNeedsBackend = true;
|
|
20814
20840
|
}
|
|
20815
20841
|
let installDemoApp = await askForConfirmation(
|
|
20816
20842
|
"Would you like to install the demo app? (component showcase)",
|
|
@@ -20936,7 +20962,9 @@ async function main9(options) {
|
|
|
20936
20962
|
overwrite: true
|
|
20937
20963
|
});
|
|
20938
20964
|
const relativeMonorepoPath = executionMode === "development" ? calculateRelativePath(projectDirNormalized, monorepoRoot) : "";
|
|
20939
|
-
const primaryPlatform = Object.values(appConfigs).find(
|
|
20965
|
+
const primaryPlatform = Object.values(appConfigs).find(
|
|
20966
|
+
(c) => c.backend !== "none"
|
|
20967
|
+
)?.backend ?? "firebase";
|
|
20940
20968
|
const rootPackageJson = generatePackageJson(
|
|
20941
20969
|
"consumer-root",
|
|
20942
20970
|
executionMode,
|
|
@@ -21297,13 +21325,16 @@ async function addPathComments(files, rootDir, dryRun, verbose) {
|
|
|
21297
21325
|
let useClientLine = -1;
|
|
21298
21326
|
let useClientValue = "";
|
|
21299
21327
|
if (!isCss) {
|
|
21300
|
-
for (let i = 0; i <
|
|
21328
|
+
for (let i = 0; i < contentLines.length; i++) {
|
|
21301
21329
|
const line = contentLines[i]?.trim();
|
|
21302
21330
|
if (line === '"use client";' || line === "'use client';") {
|
|
21303
21331
|
useClientLine = i;
|
|
21304
21332
|
useClientValue = line;
|
|
21305
21333
|
break;
|
|
21306
21334
|
}
|
|
21335
|
+
if (line?.startsWith("import ") || line?.startsWith("export ") || line?.startsWith("function ") || line?.startsWith("class ") || line?.startsWith("const ") || line?.startsWith("let ") || line?.startsWith("var ")) {
|
|
21336
|
+
break;
|
|
21337
|
+
}
|
|
21307
21338
|
}
|
|
21308
21339
|
}
|
|
21309
21340
|
const invalidFormat = isCss ? COMMENT_FORMATS[".ts"] : null;
|
package/package.json
CHANGED
|
@@ -1,24 +1,161 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
|
+
|
|
3
4
|
<head>
|
|
4
5
|
<meta charset="UTF-8" />
|
|
6
|
+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
7
|
+
|
|
8
|
+
<!-- Meta tags -->
|
|
5
9
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>DoNotDev
|
|
7
|
-
|
|
8
|
-
<!--
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
<title>DoNotDev Demo</title>
|
|
11
|
+
|
|
12
|
+
<!-- Fonts: Inter, Space Grotesk, Playfair, Roboto from @donotdev/ui/dndev.css (bundled). -->
|
|
13
|
+
|
|
14
|
+
<!-- ✅ CRITICAL CSS: ECG waveform loader -->
|
|
11
15
|
<style>
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
/* Critical above-the-fold styles */
|
|
17
|
+
html, body {
|
|
18
|
+
margin: 0;
|
|
19
|
+
padding: 0;
|
|
20
|
+
box-sizing: border-box;
|
|
21
|
+
}
|
|
22
|
+
body {
|
|
23
|
+
font-family: 'Inter', var(--font-family, ui-sans-serif, system-ui, -apple-system, sans-serif);
|
|
24
|
+
line-height: 1.5;
|
|
25
|
+
-webkit-font-smoothing: antialiased;
|
|
26
|
+
-moz-osx-font-smoothing: grayscale;
|
|
27
|
+
background: #ffffff;
|
|
28
|
+
color: #000000;
|
|
29
|
+
}
|
|
30
|
+
@media (prefers-color-scheme: dark) {
|
|
31
|
+
body {
|
|
32
|
+
background: #000000;
|
|
33
|
+
color: #ffffff;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/* Critical shell loader styles - pure CSS, instant render */
|
|
37
|
+
#shell-loader {
|
|
38
|
+
position: fixed;
|
|
39
|
+
inset: 0;
|
|
15
40
|
background: #000000;
|
|
16
|
-
|
|
41
|
+
display: flex;
|
|
42
|
+
align-items: center;
|
|
43
|
+
justify-content: center;
|
|
44
|
+
z-index: 9999;
|
|
45
|
+
opacity: 1;
|
|
46
|
+
transition: opacity 0.3s ease-out;
|
|
47
|
+
will-change: opacity;
|
|
48
|
+
margin: 0;
|
|
49
|
+
padding: 0;
|
|
50
|
+
box-sizing: border-box;
|
|
51
|
+
}
|
|
52
|
+
#shell-loader.shell-loader--fading {
|
|
53
|
+
opacity: 0;
|
|
54
|
+
pointer-events: none;
|
|
55
|
+
}
|
|
56
|
+
.shell-loader__content {
|
|
57
|
+
text-align: center;
|
|
58
|
+
color: white;
|
|
59
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
|
|
60
|
+
width: 100%;
|
|
61
|
+
max-width: 500px;
|
|
62
|
+
margin: 0;
|
|
63
|
+
padding: 0;
|
|
64
|
+
box-sizing: border-box;
|
|
65
|
+
line-height: 1.2;
|
|
66
|
+
}
|
|
67
|
+
.shell-loader__brand {
|
|
68
|
+
display: block;
|
|
69
|
+
font-size: clamp(3rem, 10vw, 5rem);
|
|
70
|
+
font-weight: 800;
|
|
71
|
+
letter-spacing: -0.05em;
|
|
72
|
+
margin: 0 0 1rem 0;
|
|
73
|
+
padding: 0;
|
|
74
|
+
box-sizing: border-box;
|
|
75
|
+
}
|
|
76
|
+
/* ECG Waveform Animation */
|
|
77
|
+
.shell-loader__dots {
|
|
78
|
+
display: block;
|
|
79
|
+
width: 300px;
|
|
80
|
+
height: 60px;
|
|
81
|
+
margin: 0 auto;
|
|
82
|
+
padding: 0;
|
|
83
|
+
box-sizing: border-box;
|
|
84
|
+
}
|
|
85
|
+
.shell-loader__dots svg {
|
|
86
|
+
width: 100%;
|
|
87
|
+
height: 100%;
|
|
88
|
+
display: block;
|
|
89
|
+
}
|
|
90
|
+
.shell-loader__dots path {
|
|
91
|
+
stroke: #667eea;
|
|
92
|
+
stroke-width: 3;
|
|
93
|
+
fill: none;
|
|
94
|
+
stroke-linecap: round;
|
|
95
|
+
stroke-linejoin: round;
|
|
96
|
+
stroke-dasharray: 400;
|
|
97
|
+
stroke-dashoffset: 400;
|
|
98
|
+
animation: ecg-draw 2s linear infinite;
|
|
99
|
+
}
|
|
100
|
+
@keyframes ecg-draw {
|
|
101
|
+
0% {
|
|
102
|
+
stroke-dashoffset: 400;
|
|
103
|
+
opacity: 0;
|
|
104
|
+
}
|
|
105
|
+
10% {
|
|
106
|
+
opacity: 1;
|
|
107
|
+
}
|
|
108
|
+
70% {
|
|
109
|
+
stroke-dashoffset: 0;
|
|
110
|
+
opacity: 1;
|
|
111
|
+
}
|
|
112
|
+
90%, 100% {
|
|
113
|
+
stroke-dashoffset: 0;
|
|
114
|
+
opacity: 0;
|
|
115
|
+
}
|
|
17
116
|
}
|
|
18
117
|
</style>
|
|
118
|
+
|
|
119
|
+
<!-- ✅ THEME DETECTION: Force dark on first visit, remember user choice -->
|
|
120
|
+
<script>
|
|
121
|
+
(function () {
|
|
122
|
+
'use strict';
|
|
123
|
+
|
|
124
|
+
function getInitialTheme() {
|
|
125
|
+
try {
|
|
126
|
+
var saved = localStorage.getItem('dndev-theme');
|
|
127
|
+
if (saved) {
|
|
128
|
+
return saved;
|
|
129
|
+
}
|
|
130
|
+
return 'dark';
|
|
131
|
+
} catch (e) {
|
|
132
|
+
return 'dark';
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
var theme = getInitialTheme();
|
|
137
|
+
document.documentElement.className = theme;
|
|
138
|
+
})();
|
|
139
|
+
</script>
|
|
19
140
|
</head>
|
|
141
|
+
|
|
20
142
|
<body>
|
|
143
|
+
<!-- ✅ SHELL LOADER: Branded loading experience before React loads -->
|
|
144
|
+
<div id="shell-loader">
|
|
145
|
+
<div class="shell-loader__content">
|
|
146
|
+
<span class="shell-loader__brand">DoNotDev</span>
|
|
147
|
+
<span class="shell-loader__dots">
|
|
148
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 60" preserveAspectRatio="xMidYMid meet">
|
|
149
|
+
<path d="M0,30 L100,30 L110,20 L120,30 L130,30 L140,5 L150,55 L160,30 L175,30 L190,20 L205,30 L300,30" />
|
|
150
|
+
</svg>
|
|
151
|
+
</span>
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
|
|
155
|
+
<!-- React mounts here -->
|
|
21
156
|
<div id="root"></div>
|
|
157
|
+
|
|
22
158
|
<script type="module" src="/src/main.tsx"></script>
|
|
23
159
|
</body>
|
|
24
|
-
|
|
160
|
+
|
|
161
|
+
</html>
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
+
// apps/demo/src/App.tsx
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
|
-
* @fileoverview Main application component
|
|
3
|
-
* @description Root application
|
|
4
|
-
* @version 0.0.
|
|
4
|
+
* @fileoverview Main application component for the demo app
|
|
5
|
+
* @description Root component that configures the application with Vite providers and layout.
|
|
6
|
+
* @version 0.0.5
|
|
5
7
|
* @since 0.0.1
|
|
6
8
|
* @author AMBROISE PARK Consulting
|
|
7
9
|
*/
|
|
8
10
|
|
|
9
11
|
import { ViteAppProviders } from '@donotdev/ui/vite';
|
|
10
12
|
|
|
11
|
-
import './config/providers';
|
|
12
13
|
import { appConfig } from './config/app';
|
|
13
14
|
|
|
14
15
|
/**
|
|
@@ -20,17 +21,10 @@ import { appConfig } from './config/app';
|
|
|
20
21
|
*
|
|
21
22
|
* Note: HomePage.tsx in src/pages/ is automatically used for the root route "/"
|
|
22
23
|
*
|
|
23
|
-
* @version 0.0.
|
|
24
|
+
* @version 0.0.5
|
|
24
25
|
* @since 0.0.1
|
|
25
26
|
* @author AMBROISE PARK Consulting
|
|
26
27
|
*/
|
|
27
28
|
export function App() {
|
|
28
|
-
return
|
|
29
|
-
<ViteAppProviders
|
|
30
|
-
config={appConfig}
|
|
31
|
-
layout={{
|
|
32
|
-
breadcrumbs: 'smart', // 'smart' | 'always' | 'never'
|
|
33
|
-
}}
|
|
34
|
-
/>
|
|
35
|
-
);
|
|
29
|
+
return <ViteAppProviders config={appConfig} layout={{ breadcrumbs: 'smart' }} />;
|
|
36
30
|
}
|
|
@@ -1,46 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Application configuration
|
|
3
|
-
* @description Defines application metadata and feature flags
|
|
4
|
-
* @version 0.0
|
|
3
|
+
* @description Defines application metadata, layout preset, and feature flags
|
|
4
|
+
* @version 0.1.0
|
|
5
5
|
* @since 0.0.1
|
|
6
6
|
* @author AMBROISE PARK Consulting
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { AppConfig } from '@donotdev/core';
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
* @version 0.0.1
|
|
15
|
-
* @since 0.0.1
|
|
16
|
-
* @author AMBROISE PARK Consulting
|
|
17
|
-
*/
|
|
18
|
-
export const APP_NAME = '{{appName}}';
|
|
11
|
+
export const APP_NAME = 'DoNotDev';
|
|
12
|
+
export const APP_SHORT_NAME = 'DoNotDev';
|
|
13
|
+
export const APP_DESCRIPTION = 'DoNotDev SaaS Template';
|
|
19
14
|
|
|
20
15
|
/**
|
|
21
|
-
* Application
|
|
16
|
+
* Application configuration
|
|
22
17
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* @author AMBROISE PARK Consulting
|
|
26
|
-
*/
|
|
27
|
-
export const APP_SHORT_NAME = '{{appShortName}}';
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Application description constant
|
|
31
|
-
*
|
|
32
|
-
* @version 0.0.1
|
|
33
|
-
* @since 0.0.1
|
|
34
|
-
* @author AMBROISE PARK Consulting
|
|
35
|
-
*/
|
|
36
|
-
export const APP_DESCRIPTION = 'DoNotDev Components Demo';
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Application configuration object
|
|
40
|
-
*
|
|
41
|
-
* @version 0.0.1
|
|
42
|
-
* @since 0.0.1
|
|
43
|
-
* @author AMBROISE PARK Consulting
|
|
18
|
+
* - preset: 'landing' is the app default. Pages can override via PageMeta.preset.
|
|
19
|
+
* - auth: Configure auth routes and menu items.
|
|
44
20
|
*/
|
|
45
21
|
export const appConfig: AppConfig = {
|
|
46
22
|
app: {
|
|
@@ -48,21 +24,9 @@ export const appConfig: AppConfig = {
|
|
|
48
24
|
shortName: APP_SHORT_NAME,
|
|
49
25
|
description: APP_DESCRIPTION,
|
|
50
26
|
},
|
|
51
|
-
preset: 'landing',
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
27
|
+
preset: 'landing',
|
|
28
|
+
auth: {
|
|
29
|
+
authRoute: '/pricing',
|
|
30
|
+
profilePath: '/profile',
|
|
55
31
|
},
|
|
56
|
-
// Optional: Override query cache defaults
|
|
57
|
-
// Framework defaults (infinite cache - cost-optimized):
|
|
58
|
-
// - staleTime: Infinity (data never becomes stale)
|
|
59
|
-
// - refetchOnWindowFocus: false (no auto-refetch on focus)
|
|
60
|
-
// - refetchOnReconnect: false (no auto-refetch on reconnect)
|
|
61
|
-
// This minimizes API costs and is ideal for single-admin apps with manual refresh buttons.
|
|
62
|
-
// Uncomment below to enable auto-refetch behavior:
|
|
63
|
-
// query: {
|
|
64
|
-
// staleTime: 1000 * 60 * 5, // 5 minutes - data becomes stale after 5 minutes
|
|
65
|
-
// refetchOnWindowFocus: true, // Automatically refetch when window regains focus
|
|
66
|
-
// refetchOnReconnect: true, // Automatically refetch when network reconnects
|
|
67
|
-
// },
|
|
68
32
|
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { defineEntity } from '@donotdev/core';
|
|
2
|
+
|
|
3
|
+
export const productEntity = defineEntity({
|
|
4
|
+
name: 'Product',
|
|
5
|
+
collection: 'products',
|
|
6
|
+
fields: {
|
|
7
|
+
name: {
|
|
8
|
+
type: 'text',
|
|
9
|
+
visibility: 'user',
|
|
10
|
+
validation: { required: true, minLength: 3 },
|
|
11
|
+
},
|
|
12
|
+
description: {
|
|
13
|
+
type: 'textarea',
|
|
14
|
+
visibility: 'user',
|
|
15
|
+
},
|
|
16
|
+
price: {
|
|
17
|
+
type: 'number',
|
|
18
|
+
visibility: 'user',
|
|
19
|
+
validation: { required: true, min: 0 },
|
|
20
|
+
},
|
|
21
|
+
category: {
|
|
22
|
+
type: 'select',
|
|
23
|
+
visibility: 'user',
|
|
24
|
+
validation: {
|
|
25
|
+
options: [
|
|
26
|
+
{ value: 'electronics', label: 'Electronics' },
|
|
27
|
+
{ value: 'clothing', label: 'Clothing' },
|
|
28
|
+
{ value: 'food', label: 'Food & Drink' },
|
|
29
|
+
{ value: 'other', label: 'Other' },
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
image: {
|
|
34
|
+
type: 'image',
|
|
35
|
+
visibility: 'user',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
});
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
/* apps/demo/src/globals.css */
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/* 1. Group all imports at the top. */
|
|
4
|
+
@import '@donotdev/ui/dndev.css';
|
|
4
5
|
@import './themes.css';
|
|
6
|
+
|
|
7
|
+
/* 2. App-specific overrides — DO NOT set --font-family here,
|
|
8
|
+
it would clobber theme overrides (dark/terminal set it to mono) */
|