@donotdev/cli 0.0.8 → 0.0.9
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 +158 -74
- package/dist/bin/commands/create-app.js +43 -6
- package/dist/bin/commands/create-project.js +60 -7
- package/dist/bin/commands/deploy.js +111 -22
- package/dist/bin/dndev.js +7 -4
- package/dist/bin/donotdev.js +7 -4
- package/dist/index.js +174 -30
- package/package.json +4 -3
- package/templates/app-next/src/config/app.ts.example +1 -1
- package/templates/app-vite/index.html.example +24 -2
- package/templates/app-vite/src/config/app.ts.example +1 -1
- package/templates/app-vite/src/pages/FormPageExample.tsx.example +8 -5
- package/templates/app-vite/src/pages/ListPageExample.tsx.example +4 -7
- package/templates/root-consumer/.firebaserc.example +5 -0
- package/templates/root-consumer/entities/ExampleEntity.ts.example +2 -1
- package/templates/root-consumer/entities/demo.ts.example +1 -1
- package/templates/root-consumer/firestore.indexes.json.example +4 -0
- package/templates/root-consumer/firestore.rules.example +11 -0
- package/templates/root-consumer/guides/dndev/COMPONENTS_CRUD.md.example +9 -6
- package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +329 -57
- package/templates/root-consumer/guides/wai-way/entity_patterns.md.example +1 -1
- package/templates/root-consumer/storage.rules.example +8 -0
|
@@ -8834,7 +8834,7 @@ function generatePackageJson(templateName, mode, options = {}) {
|
|
|
8834
8834
|
"dependencies-matrix.json not found. This command requires the matrix file."
|
|
8835
8835
|
);
|
|
8836
8836
|
}
|
|
8837
|
-
const { matrix
|
|
8837
|
+
const { matrix } = matrixResult;
|
|
8838
8838
|
const template = matrix.templateMapping?.[templateName];
|
|
8839
8839
|
if (!template) {
|
|
8840
8840
|
throw new Error(`Template "${templateName}" not found in matrix`);
|
|
@@ -8898,6 +8898,7 @@ function generatePackageJson(templateName, mode, options = {}) {
|
|
|
8898
8898
|
}
|
|
8899
8899
|
}
|
|
8900
8900
|
if (templateName.includes("functions")) {
|
|
8901
|
+
result.main = "lib/index.js";
|
|
8901
8902
|
result.engines = { node: "20" };
|
|
8902
8903
|
if (options.appName) {
|
|
8903
8904
|
const platform = templateName.includes("vercel") ? "Vercel" : "Firebase";
|
|
@@ -9025,6 +9026,8 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9025
9026
|
s.start(`Creating app: ${appName}`);
|
|
9026
9027
|
await ensureDir(appDir);
|
|
9027
9028
|
const templateDir = appTemplate === "demo" ? "app-demo" : appTemplate === "nextjs" ? "app-next" : "app-vite";
|
|
9029
|
+
const firebaseProjectId = (appConfig?.firebaseProjectId ?? "").trim() || appName.toLowerCase().replace(/\s+/g, "-");
|
|
9030
|
+
const firebaseRegion = appConfig?.firebaseRegion ?? "europe-west1";
|
|
9028
9031
|
const replacements = {
|
|
9029
9032
|
projectName: appName,
|
|
9030
9033
|
appName,
|
|
@@ -9033,11 +9036,14 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9033
9036
|
needsCRUD: Boolean(appConfig.needsCRUD),
|
|
9034
9037
|
setupGithubActions: false,
|
|
9035
9038
|
appNames: [appName],
|
|
9036
|
-
firebaseProjectId
|
|
9039
|
+
firebaseProjectId,
|
|
9040
|
+
firebaseRegion,
|
|
9037
9041
|
firebaseSecretName: appName.toUpperCase().replace(/-/g, "_"),
|
|
9038
9042
|
monorepoRelativePath: "../../packages/tooling",
|
|
9039
9043
|
appTemplate,
|
|
9040
|
-
isNextjs: appTemplate === "nextjs"
|
|
9044
|
+
isNextjs: appTemplate === "nextjs",
|
|
9045
|
+
YOUR_FIREBASE_PROJECT_ID: firebaseProjectId,
|
|
9046
|
+
YOUR_REGION: firebaseRegion
|
|
9041
9047
|
};
|
|
9042
9048
|
const templateSourceDir = joinPath(templatesRoot, templateDir);
|
|
9043
9049
|
const templateFiles = await glob("**/*", {
|
|
@@ -9130,6 +9136,32 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9130
9136
|
await replacePlaceholders(firebaseJsonDest, replacements);
|
|
9131
9137
|
}
|
|
9132
9138
|
}
|
|
9139
|
+
const firebasercSource = joinPath(
|
|
9140
|
+
deploymentTemplateDir,
|
|
9141
|
+
".firebaserc.example"
|
|
9142
|
+
);
|
|
9143
|
+
if (pathExists(firebasercSource)) {
|
|
9144
|
+
const firebasercDest = joinPath(appDir, ".firebaserc");
|
|
9145
|
+
await copy(firebasercSource, firebasercDest);
|
|
9146
|
+
if (await isTextFile(firebasercDest)) {
|
|
9147
|
+
await replacePlaceholders(firebasercDest, replacements);
|
|
9148
|
+
}
|
|
9149
|
+
}
|
|
9150
|
+
if (appConfig.needsBackend && appConfig.backendPlatform === "firebase") {
|
|
9151
|
+
const rulesFiles = [
|
|
9152
|
+
"firestore.rules.example",
|
|
9153
|
+
"firestore.indexes.json.example",
|
|
9154
|
+
"storage.rules.example"
|
|
9155
|
+
];
|
|
9156
|
+
for (const example of rulesFiles) {
|
|
9157
|
+
const src = joinPath(deploymentTemplateDir, example);
|
|
9158
|
+
if (pathExists(src)) {
|
|
9159
|
+
const destName = example.replace(".example", "");
|
|
9160
|
+
const dest = joinPath(appDir, destName);
|
|
9161
|
+
await copy(src, dest);
|
|
9162
|
+
}
|
|
9163
|
+
}
|
|
9164
|
+
}
|
|
9133
9165
|
if (appTemplate === "nextjs" || appConfig.needsBackend && appConfig.backendPlatform === "vercel") {
|
|
9134
9166
|
const vercelJsonSource = joinPath(
|
|
9135
9167
|
deploymentTemplateDir,
|
|
@@ -9155,12 +9187,15 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9155
9187
|
}
|
|
9156
9188
|
if (isInteractive) {
|
|
9157
9189
|
Se("\u{1F389} App created successfully!");
|
|
9190
|
+
const firebaseStep = appConfig.needsBackend && appConfig.backendPlatform === "firebase" ? `2. Set Firebase project: cd apps/${appName} && firebase use --add (or edit .firebase rc)
|
|
9191
|
+
3. bun install
|
|
9192
|
+
4. bun run dev` : `2. bun install
|
|
9193
|
+
3. bun run dev`;
|
|
9158
9194
|
Me(
|
|
9159
9195
|
`Next steps:
|
|
9160
9196
|
|
|
9161
9197
|
1. cd apps/${appName}
|
|
9162
|
-
|
|
9163
|
-
3. bun run dev
|
|
9198
|
+
${firebaseStep}
|
|
9164
9199
|
|
|
9165
9200
|
Happy coding!`,
|
|
9166
9201
|
"\u{1F4CB} Next Steps"
|
|
@@ -9496,6 +9531,8 @@ async function main(options) {
|
|
|
9496
9531
|
overwrite: true
|
|
9497
9532
|
});
|
|
9498
9533
|
const rootTemplateDir = joinPath(templatesRoot, "root-consumer");
|
|
9534
|
+
const firebaseProjectId = projectName.toLowerCase().replace(/\s+/g, "-");
|
|
9535
|
+
const firebaseRegion = "europe-west1";
|
|
9499
9536
|
const rootReplacements = {
|
|
9500
9537
|
projectName,
|
|
9501
9538
|
appNames: isMergeMode ? allAppNames : appNames,
|
|
@@ -9504,12 +9541,22 @@ async function main(options) {
|
|
|
9504
9541
|
monorepoRelativePath: relativeMonorepoPath,
|
|
9505
9542
|
appTemplate: "vite",
|
|
9506
9543
|
isNextjs: false,
|
|
9507
|
-
firebaseProjectId
|
|
9544
|
+
firebaseProjectId,
|
|
9545
|
+
firebaseRegion,
|
|
9508
9546
|
firebaseSecretName: projectName.toUpperCase().replace(/-/g, "_"),
|
|
9547
|
+
YOUR_FIREBASE_PROJECT_ID: firebaseProjectId,
|
|
9548
|
+
YOUR_REGION: firebaseRegion,
|
|
9509
9549
|
needsAuth,
|
|
9510
9550
|
needsOAuth,
|
|
9511
9551
|
needsBilling
|
|
9512
9552
|
};
|
|
9553
|
+
const firebaseRootFiles = /* @__PURE__ */ new Set([
|
|
9554
|
+
"firebase.json.example",
|
|
9555
|
+
".firebaserc.example",
|
|
9556
|
+
"firestore.rules.example",
|
|
9557
|
+
"firestore.indexes.json.example",
|
|
9558
|
+
"storage.rules.example"
|
|
9559
|
+
]);
|
|
9513
9560
|
const files = await glob("**/*", {
|
|
9514
9561
|
cwd: rootTemplateDir,
|
|
9515
9562
|
dot: true,
|
|
@@ -9517,6 +9564,7 @@ async function main(options) {
|
|
|
9517
9564
|
});
|
|
9518
9565
|
for (const file of files) {
|
|
9519
9566
|
if (file === "package.json.example") continue;
|
|
9567
|
+
if (firebaseRootFiles.has(file)) continue;
|
|
9520
9568
|
const sourcePath = joinPath(rootTemplateDir, file);
|
|
9521
9569
|
let destFileName = file;
|
|
9522
9570
|
if (destFileName.endsWith(".example")) {
|
|
@@ -9591,6 +9639,8 @@ async function main(options) {
|
|
|
9591
9639
|
}
|
|
9592
9640
|
}
|
|
9593
9641
|
if (installDemoApp) {
|
|
9642
|
+
const demoFirebaseProjectId = projectName.toLowerCase().replace(/\s+/g, "-");
|
|
9643
|
+
const demoFirebaseRegion = "europe-west1";
|
|
9594
9644
|
await copyTemplateFiles(demoTemplateDir, demoAppDir, {
|
|
9595
9645
|
projectName,
|
|
9596
9646
|
appName: "demo",
|
|
@@ -9598,8 +9648,11 @@ async function main(options) {
|
|
|
9598
9648
|
needsCRUD: false,
|
|
9599
9649
|
setupGithubActions: false,
|
|
9600
9650
|
appNames,
|
|
9601
|
-
firebaseProjectId:
|
|
9651
|
+
firebaseProjectId: demoFirebaseProjectId,
|
|
9652
|
+
firebaseRegion: demoFirebaseRegion,
|
|
9602
9653
|
firebaseSecretName: projectName.toUpperCase().replace(/-/g, "_"),
|
|
9654
|
+
YOUR_FIREBASE_PROJECT_ID: demoFirebaseProjectId,
|
|
9655
|
+
YOUR_REGION: demoFirebaseRegion,
|
|
9603
9656
|
monorepoRelativePath: executionMode === "development" ? calculateRelativePath(projectDirNormalized, monorepoRoot) : "",
|
|
9604
9657
|
appTemplate: "demo"
|
|
9605
9658
|
});
|
|
@@ -7960,8 +7960,10 @@ function executeFirebaseCommand(args, options) {
|
|
|
7960
7960
|
errorOutput
|
|
7961
7961
|
};
|
|
7962
7962
|
}
|
|
7963
|
-
function buildFirebaseDeployArgs(
|
|
7964
|
-
const
|
|
7963
|
+
function buildFirebaseDeployArgs(deployTargets, projectId, debug, force) {
|
|
7964
|
+
const targets = Array.isArray(deployTargets) ? deployTargets : [deployTargets];
|
|
7965
|
+
const targetString = targets.join(",");
|
|
7966
|
+
const args = ["deploy", "--only", targetString, "--non-interactive"];
|
|
7965
7967
|
if (projectId) {
|
|
7966
7968
|
args.push("--project", projectId);
|
|
7967
7969
|
}
|
|
@@ -8523,6 +8525,47 @@ To fix this, run:
|
|
|
8523
8525
|
}
|
|
8524
8526
|
}
|
|
8525
8527
|
|
|
8528
|
+
// packages/tooling/src/apps/deploy-rules.ts
|
|
8529
|
+
init_utils();
|
|
8530
|
+
async function deployRules(appDir, serviceAccountPath, projectId, config, options) {
|
|
8531
|
+
const targets = [];
|
|
8532
|
+
if (options.firestore) {
|
|
8533
|
+
targets.push("firestore:rules");
|
|
8534
|
+
}
|
|
8535
|
+
if (options.firestoreIndexes) {
|
|
8536
|
+
targets.push("firestore:indexes");
|
|
8537
|
+
}
|
|
8538
|
+
if (options.storage) {
|
|
8539
|
+
targets.push("storage");
|
|
8540
|
+
}
|
|
8541
|
+
if (targets.length === 0) {
|
|
8542
|
+
return;
|
|
8543
|
+
}
|
|
8544
|
+
const targetNames = targets.join(", ");
|
|
8545
|
+
const s = Y2();
|
|
8546
|
+
s.start(`Deploying ${targetNames}...`);
|
|
8547
|
+
const args = buildFirebaseDeployArgs(targets, projectId, config.debug);
|
|
8548
|
+
const result = executeFirebaseCommand(args, {
|
|
8549
|
+
cwd: appDir,
|
|
8550
|
+
serviceAccountPath,
|
|
8551
|
+
projectId,
|
|
8552
|
+
debug: config.debug
|
|
8553
|
+
});
|
|
8554
|
+
if (result.error) {
|
|
8555
|
+
s.stop("Rules deployment failed");
|
|
8556
|
+
throw result.error;
|
|
8557
|
+
}
|
|
8558
|
+
if (!result.success) {
|
|
8559
|
+
s.stop("Rules deployment failed");
|
|
8560
|
+
handleDeploymentFailure(
|
|
8561
|
+
result,
|
|
8562
|
+
`firebase ${args.join(" ")}`,
|
|
8563
|
+
serviceAccountPath
|
|
8564
|
+
);
|
|
8565
|
+
}
|
|
8566
|
+
s.stop(`${targetNames} deployed successfully`);
|
|
8567
|
+
}
|
|
8568
|
+
|
|
8526
8569
|
// packages/tooling/src/apps/deploy-utils.ts
|
|
8527
8570
|
init_utils();
|
|
8528
8571
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
@@ -8643,6 +8686,9 @@ function validateFirebaseJson(appDir) {
|
|
|
8643
8686
|
valid: false,
|
|
8644
8687
|
hasHosting: false,
|
|
8645
8688
|
hasFunctions: false,
|
|
8689
|
+
hasFirestoreRules: false,
|
|
8690
|
+
hasFirestoreIndexes: false,
|
|
8691
|
+
hasStorageRules: false,
|
|
8646
8692
|
errors: [`firebase.json not found at: ${firebaseJsonPath}`]
|
|
8647
8693
|
};
|
|
8648
8694
|
}
|
|
@@ -8655,11 +8701,17 @@ function validateFirebaseJson(appDir) {
|
|
|
8655
8701
|
}
|
|
8656
8702
|
const hasHosting = !!config.hosting;
|
|
8657
8703
|
const hasFunctions = !!config.functions && Array.isArray(config.functions);
|
|
8704
|
+
const hasFirestoreRules = !!config.firestore?.rules && pathExists(joinPath(appDir, config.firestore.rules));
|
|
8705
|
+
const hasFirestoreIndexes = !!config.firestore?.indexes && pathExists(joinPath(appDir, config.firestore.indexes));
|
|
8706
|
+
const hasStorageRules = !!config.storage?.rules && pathExists(joinPath(appDir, config.storage.rules));
|
|
8658
8707
|
return {
|
|
8659
8708
|
valid: true,
|
|
8660
8709
|
projectId: config.projectId,
|
|
8661
8710
|
hasHosting,
|
|
8662
8711
|
hasFunctions,
|
|
8712
|
+
hasFirestoreRules,
|
|
8713
|
+
hasFirestoreIndexes,
|
|
8714
|
+
hasStorageRules,
|
|
8663
8715
|
errors: []
|
|
8664
8716
|
};
|
|
8665
8717
|
} catch (error2) {
|
|
@@ -8667,6 +8719,9 @@ function validateFirebaseJson(appDir) {
|
|
|
8667
8719
|
valid: false,
|
|
8668
8720
|
hasHosting: false,
|
|
8669
8721
|
hasFunctions: false,
|
|
8722
|
+
hasFirestoreRules: false,
|
|
8723
|
+
hasFirestoreIndexes: false,
|
|
8724
|
+
hasStorageRules: false,
|
|
8670
8725
|
errors: [
|
|
8671
8726
|
`Invalid JSON format: ${error2 instanceof DoNotDevError ? error2.message : error2 instanceof Error ? error2.message : String(error2)}`
|
|
8672
8727
|
]
|
|
@@ -8831,16 +8886,36 @@ async function main(options = {}) {
|
|
|
8831
8886
|
hint: "Deploy cloud functions"
|
|
8832
8887
|
});
|
|
8833
8888
|
}
|
|
8889
|
+
const hasRules = firebaseConfig2.hasFirestoreRules || firebaseConfig2.hasFirestoreIndexes || firebaseConfig2.hasStorageRules;
|
|
8890
|
+
if (hasRules) {
|
|
8891
|
+
choices.push({
|
|
8892
|
+
title: "Rules only",
|
|
8893
|
+
value: "rules",
|
|
8894
|
+
hint: "Deploy Firestore/Storage rules"
|
|
8895
|
+
});
|
|
8896
|
+
}
|
|
8834
8897
|
if (firebaseConfig2.hasHosting && firebaseConfig2.hasFunctions) {
|
|
8835
8898
|
choices.push({
|
|
8836
|
-
title: "
|
|
8899
|
+
title: "Frontend + Functions",
|
|
8837
8900
|
value: "both",
|
|
8838
|
-
hint: "Deploy
|
|
8901
|
+
hint: "Deploy hosting and functions"
|
|
8902
|
+
});
|
|
8903
|
+
}
|
|
8904
|
+
const deployableKindsCount = [
|
|
8905
|
+
firebaseConfig2.hasHosting,
|
|
8906
|
+
firebaseConfig2.hasFunctions,
|
|
8907
|
+
hasRules
|
|
8908
|
+
].filter(Boolean).length;
|
|
8909
|
+
if (deployableKindsCount > 1) {
|
|
8910
|
+
choices.push({
|
|
8911
|
+
title: "All",
|
|
8912
|
+
value: "all",
|
|
8913
|
+
hint: "Deploy everything (hosting, functions, rules)"
|
|
8839
8914
|
});
|
|
8840
8915
|
}
|
|
8841
8916
|
if (choices.length === 0) {
|
|
8842
8917
|
log.error(
|
|
8843
|
-
"No deployment targets found. firebase.json must have hosting or
|
|
8918
|
+
"No deployment targets found. firebase.json must have hosting, functions, or rules configuration."
|
|
8844
8919
|
);
|
|
8845
8920
|
process.exit(1);
|
|
8846
8921
|
}
|
|
@@ -8885,13 +8960,28 @@ async function main(options = {}) {
|
|
|
8885
8960
|
showFirebaseJsonError(firebaseConfig.errors, appDir, deploymentType);
|
|
8886
8961
|
process.exit(1);
|
|
8887
8962
|
}
|
|
8888
|
-
|
|
8889
|
-
|
|
8890
|
-
|
|
8891
|
-
|
|
8892
|
-
|
|
8893
|
-
|
|
8894
|
-
|
|
8963
|
+
const shouldDeployFrontend = (deploymentType === "frontend" || deploymentType === "both" || deploymentType === "all") && firebaseConfig.hasHosting;
|
|
8964
|
+
const shouldDeployFunctions = (deploymentType === "functions" || deploymentType === "both" || deploymentType === "all") && firebaseConfig.hasFunctions;
|
|
8965
|
+
const shouldDeployRules = (deploymentType === "rules" || deploymentType === "all") && (firebaseConfig.hasFirestoreRules || firebaseConfig.hasFirestoreIndexes || firebaseConfig.hasStorageRules);
|
|
8966
|
+
if (deploymentType === "frontend" && !firebaseConfig.hasHosting) {
|
|
8967
|
+
log.error(
|
|
8968
|
+
"firebase.json does not contain hosting configuration, but frontend deployment was requested."
|
|
8969
|
+
);
|
|
8970
|
+
process.exit(1);
|
|
8971
|
+
}
|
|
8972
|
+
if (deploymentType === "functions" && !firebaseConfig.hasFunctions) {
|
|
8973
|
+
log.error(
|
|
8974
|
+
"firebase.json does not contain functions configuration, but functions deployment was requested."
|
|
8975
|
+
);
|
|
8976
|
+
process.exit(1);
|
|
8977
|
+
}
|
|
8978
|
+
if (deploymentType === "rules" && !shouldDeployRules) {
|
|
8979
|
+
log.error(
|
|
8980
|
+
"firebase.json does not contain rules configuration, but rules deployment was requested."
|
|
8981
|
+
);
|
|
8982
|
+
process.exit(1);
|
|
8983
|
+
}
|
|
8984
|
+
if (shouldDeployFrontend) {
|
|
8895
8985
|
const buildStatus = validateBuild(appDir);
|
|
8896
8986
|
let shouldBuild = false;
|
|
8897
8987
|
if (!buildStatus.exists || buildStatus.isEmpty) {
|
|
@@ -8934,14 +9024,6 @@ async function main(options = {}) {
|
|
|
8934
9024
|
}
|
|
8935
9025
|
}
|
|
8936
9026
|
}
|
|
8937
|
-
if (deploymentType === "functions" || deploymentType === "both") {
|
|
8938
|
-
if (!firebaseConfig.hasFunctions) {
|
|
8939
|
-
log.error(
|
|
8940
|
-
"firebase.json does not contain functions configuration, but functions deployment was requested."
|
|
8941
|
-
);
|
|
8942
|
-
process.exit(1);
|
|
8943
|
-
}
|
|
8944
|
-
}
|
|
8945
9027
|
clearFirebaseCache(appDir);
|
|
8946
9028
|
Me(
|
|
8947
9029
|
`App: ${appName}
|
|
@@ -8950,10 +9032,10 @@ Deployment: ${deploymentType}
|
|
|
8950
9032
|
Service Account: ${serviceAccountResult.info.clientEmail}`,
|
|
8951
9033
|
"Deployment Configuration"
|
|
8952
9034
|
);
|
|
8953
|
-
if (
|
|
9035
|
+
if (shouldDeployFrontend) {
|
|
8954
9036
|
await deployFrontend(appDir, serviceAccountPath, config.project, config);
|
|
8955
9037
|
}
|
|
8956
|
-
if (
|
|
9038
|
+
if (shouldDeployFunctions) {
|
|
8957
9039
|
await deployFunctions(
|
|
8958
9040
|
appDir,
|
|
8959
9041
|
serviceAccountPath,
|
|
@@ -8961,6 +9043,13 @@ Service Account: ${serviceAccountResult.info.clientEmail}`,
|
|
|
8961
9043
|
config
|
|
8962
9044
|
);
|
|
8963
9045
|
}
|
|
9046
|
+
if (shouldDeployRules) {
|
|
9047
|
+
await deployRules(appDir, serviceAccountPath, config.project, config, {
|
|
9048
|
+
firestore: firebaseConfig.hasFirestoreRules,
|
|
9049
|
+
firestoreIndexes: firebaseConfig.hasFirestoreIndexes,
|
|
9050
|
+
storage: firebaseConfig.hasStorageRules
|
|
9051
|
+
});
|
|
9052
|
+
}
|
|
8964
9053
|
Se("Deployment completed successfully!");
|
|
8965
9054
|
} catch (error2) {
|
|
8966
9055
|
if (error2 instanceof DoNotDevError) {
|
package/dist/bin/dndev.js
CHANGED
|
@@ -46,7 +46,7 @@ Usage: dndev <command>[:<app>] [options]
|
|
|
46
46
|
|
|
47
47
|
Commands:
|
|
48
48
|
init, create-project Create a new DoNotDev project
|
|
49
|
-
create-app [name] Add app
|
|
49
|
+
create-app [name] Add app (--builder vite|next, --functions, --project <id>)
|
|
50
50
|
dev [app] Start development server
|
|
51
51
|
build [app] Build for production
|
|
52
52
|
preview [app] Preview production build
|
|
@@ -66,7 +66,8 @@ Examples:
|
|
|
66
66
|
dndev init my-project Create a new project
|
|
67
67
|
dndev create-app Interactive app creation
|
|
68
68
|
dndev create-app my-app Create 'my-app' with defaults (vite, no functions)
|
|
69
|
-
dndev create-app my-app --builder next --functions
|
|
69
|
+
dndev create-app my-app --builder next --functions Next.js + functions
|
|
70
|
+
dndev create-app my-app --functions --project my-fb-id Set Firebase project (2-min setup)
|
|
70
71
|
dndev dev Start dev server
|
|
71
72
|
dndev dev:web Start dev server for 'web' app
|
|
72
73
|
dndev wai Output WAI-WAY activation prompt
|
|
@@ -90,14 +91,16 @@ program.command("init [name]").alias("create-project").description("Create a new
|
|
|
90
91
|
const { main } = await import("./commands/create-project.js");
|
|
91
92
|
await main({ projectName: name });
|
|
92
93
|
});
|
|
93
|
-
program.command("create-app [name]").description("Add a new app to existing project").option("--name <name>", "App name (non-interactive)").option("--builder <builder>", "Framework: vite or next (default: vite)").option("--functions", "Include Firebase functions").action(async (name, options) => {
|
|
94
|
+
program.command("create-app [name]").description("Add a new app to existing project").option("--name <name>", "App name (non-interactive)").option("--builder <builder>", "Framework: vite or next (default: vite)").option("--functions", "Include Firebase functions").option("--project <id>", "Firebase project ID (default: app name)").option("--region <region>", "Firebase region (default: europe-west1)").action(async (name, options) => {
|
|
94
95
|
const { main } = await import("./commands/create-app.js");
|
|
95
96
|
const appName = name || options.name;
|
|
96
97
|
if (appName) {
|
|
97
98
|
await main({
|
|
98
99
|
name: appName,
|
|
99
100
|
builder: options.builder,
|
|
100
|
-
functions: options.functions
|
|
101
|
+
functions: options.functions,
|
|
102
|
+
firebaseProjectId: options.project,
|
|
103
|
+
firebaseRegion: options.region
|
|
101
104
|
});
|
|
102
105
|
} else {
|
|
103
106
|
await main();
|
package/dist/bin/donotdev.js
CHANGED
|
@@ -46,7 +46,7 @@ Usage: dndev <command>[:<app>] [options]
|
|
|
46
46
|
|
|
47
47
|
Commands:
|
|
48
48
|
init, create-project Create a new DoNotDev project
|
|
49
|
-
create-app [name] Add app
|
|
49
|
+
create-app [name] Add app (--builder vite|next, --functions, --project <id>)
|
|
50
50
|
dev [app] Start development server
|
|
51
51
|
build [app] Build for production
|
|
52
52
|
preview [app] Preview production build
|
|
@@ -66,7 +66,8 @@ Examples:
|
|
|
66
66
|
dndev init my-project Create a new project
|
|
67
67
|
dndev create-app Interactive app creation
|
|
68
68
|
dndev create-app my-app Create 'my-app' with defaults (vite, no functions)
|
|
69
|
-
dndev create-app my-app --builder next --functions
|
|
69
|
+
dndev create-app my-app --builder next --functions Next.js + functions
|
|
70
|
+
dndev create-app my-app --functions --project my-fb-id Set Firebase project (2-min setup)
|
|
70
71
|
dndev dev Start dev server
|
|
71
72
|
dndev dev:web Start dev server for 'web' app
|
|
72
73
|
dndev wai Output WAI-WAY activation prompt
|
|
@@ -90,14 +91,16 @@ program.command("init [name]").alias("create-project").description("Create a new
|
|
|
90
91
|
const { main } = await import("./commands/create-project.js");
|
|
91
92
|
await main({ projectName: name });
|
|
92
93
|
});
|
|
93
|
-
program.command("create-app [name]").description("Add a new app to existing project").option("--name <name>", "App name (non-interactive)").option("--builder <builder>", "Framework: vite or next (default: vite)").option("--functions", "Include Firebase functions").action(async (name, options) => {
|
|
94
|
+
program.command("create-app [name]").description("Add a new app to existing project").option("--name <name>", "App name (non-interactive)").option("--builder <builder>", "Framework: vite or next (default: vite)").option("--functions", "Include Firebase functions").option("--project <id>", "Firebase project ID (default: app name)").option("--region <region>", "Firebase region (default: europe-west1)").action(async (name, options) => {
|
|
94
95
|
const { main } = await import("./commands/create-app.js");
|
|
95
96
|
const appName = name || options.name;
|
|
96
97
|
if (appName) {
|
|
97
98
|
await main({
|
|
98
99
|
name: appName,
|
|
99
100
|
builder: options.builder,
|
|
100
|
-
functions: options.functions
|
|
101
|
+
functions: options.functions,
|
|
102
|
+
firebaseProjectId: options.project,
|
|
103
|
+
firebaseRegion: options.region
|
|
101
104
|
});
|
|
102
105
|
} else {
|
|
103
106
|
await main();
|