@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
package/dist/bin/commands/dev.js
CHANGED
|
@@ -7511,11 +7511,39 @@ var init_PathResolver = __esm({
|
|
|
7511
7511
|
});
|
|
7512
7512
|
|
|
7513
7513
|
// packages/tooling/src/utils/errors.ts
|
|
7514
|
-
var DoNotDevError;
|
|
7514
|
+
var DO_NOT_DEV_ERROR_CODES, DoNotDevError;
|
|
7515
7515
|
var init_errors = __esm({
|
|
7516
7516
|
"packages/tooling/src/utils/errors.ts"() {
|
|
7517
7517
|
"use strict";
|
|
7518
7518
|
init_utils();
|
|
7519
|
+
DO_NOT_DEV_ERROR_CODES = {
|
|
7520
|
+
CONFIGURATION_ERROR: "configuration-error",
|
|
7521
|
+
CONFIG_NOT_FOUND: "config-not-found",
|
|
7522
|
+
CONFIG_INVALID: "config-invalid",
|
|
7523
|
+
PATH_RESOLUTION_ERROR: "path-resolution-error",
|
|
7524
|
+
FILE_OPERATION_ERROR: "file-operation-error",
|
|
7525
|
+
FILE_NOT_FOUND: "file-not-found",
|
|
7526
|
+
PERMISSION_DENIED: "permission-denied",
|
|
7527
|
+
GENERATION_ERROR: "generation-error",
|
|
7528
|
+
TEMPLATE_ERROR: "template-error",
|
|
7529
|
+
TEMPLATE_NOT_FOUND: "template-not-found",
|
|
7530
|
+
CLI_EXECUTION_ERROR: "cli-execution-error",
|
|
7531
|
+
COMMAND_NOT_FOUND: "command-not-found",
|
|
7532
|
+
COMMAND_FAILED: "command-failed",
|
|
7533
|
+
VALIDATION_ERROR: "validation-error",
|
|
7534
|
+
SCHEMA_ERROR: "schema-error",
|
|
7535
|
+
DEPENDENCY_ERROR: "dependency-error",
|
|
7536
|
+
DEPENDENCY_NOT_FOUND: "dependency-not-found",
|
|
7537
|
+
DEPENDENCY_VERSION_ERROR: "dependency-version-error",
|
|
7538
|
+
INVALID_ARGUMENT: "invalid-argument",
|
|
7539
|
+
MISSING_ARGUMENT: "missing-argument",
|
|
7540
|
+
MISSING_PROJECT_ID: "missing-project-id",
|
|
7541
|
+
FIREBASE_CLI_ERROR: "firebase-cli-error",
|
|
7542
|
+
DEPLOYMENT_FAILED: "deployment-failed",
|
|
7543
|
+
OPERATION_CANCELLED: "operation-cancelled",
|
|
7544
|
+
TIMEOUT_ERROR: "timeout-error",
|
|
7545
|
+
UNKNOWN_ERROR: "unknown-error"
|
|
7546
|
+
};
|
|
7519
7547
|
DoNotDevError = class _DoNotDevError extends Error {
|
|
7520
7548
|
/** The error code categorizing this error */
|
|
7521
7549
|
code;
|
|
@@ -7535,7 +7563,7 @@ var init_errors = __esm({
|
|
|
7535
7563
|
* @param {Record<string, any>} [options.context] - Additional context data
|
|
7536
7564
|
* @param {boolean} [options.displayable=true] - Whether this error should be displayed to the user
|
|
7537
7565
|
*/
|
|
7538
|
-
constructor(message, code =
|
|
7566
|
+
constructor(message, code = DO_NOT_DEV_ERROR_CODES.UNKNOWN_ERROR, options) {
|
|
7539
7567
|
super(message);
|
|
7540
7568
|
this.name = "DoNotDevError";
|
|
7541
7569
|
this.code = code;
|
|
@@ -7566,7 +7594,7 @@ var init_errors = __esm({
|
|
|
7566
7594
|
* @param {boolean} [options.displayable=true] - Whether this error should be displayed to the user
|
|
7567
7595
|
* @returns {DoNotDevError} New DoNotDev error wrapping the original
|
|
7568
7596
|
*/
|
|
7569
|
-
static from(error2, context, code =
|
|
7597
|
+
static from(error2, context, code = DO_NOT_DEV_ERROR_CODES.UNKNOWN_ERROR, options) {
|
|
7570
7598
|
if (!(error2 instanceof Error)) {
|
|
7571
7599
|
return new _DoNotDevError(
|
|
7572
7600
|
`Unknown error: ${String(error2)}`,
|
|
@@ -7603,21 +7631,21 @@ var init_errors = __esm({
|
|
|
7603
7631
|
}
|
|
7604
7632
|
const message = error2.message.toLowerCase();
|
|
7605
7633
|
if (error2.name === "ValidationError" || message.includes("validation")) {
|
|
7606
|
-
return
|
|
7634
|
+
return DO_NOT_DEV_ERROR_CODES.VALIDATION_ERROR;
|
|
7607
7635
|
}
|
|
7608
7636
|
if (message.includes("not found") || message.includes("no such file")) {
|
|
7609
|
-
return
|
|
7637
|
+
return DO_NOT_DEV_ERROR_CODES.FILE_NOT_FOUND;
|
|
7610
7638
|
}
|
|
7611
7639
|
if (message.includes("permission") || message.includes("access denied")) {
|
|
7612
|
-
return
|
|
7640
|
+
return DO_NOT_DEV_ERROR_CODES.PERMISSION_DENIED;
|
|
7613
7641
|
}
|
|
7614
7642
|
if (message.includes("timeout") || message.includes("timed out")) {
|
|
7615
|
-
return
|
|
7643
|
+
return DO_NOT_DEV_ERROR_CODES.TIMEOUT_ERROR;
|
|
7616
7644
|
}
|
|
7617
7645
|
if (message.includes("dependency") || message.includes("module not found")) {
|
|
7618
|
-
return
|
|
7646
|
+
return DO_NOT_DEV_ERROR_CODES.DEPENDENCY_ERROR;
|
|
7619
7647
|
}
|
|
7620
|
-
return
|
|
7648
|
+
return DO_NOT_DEV_ERROR_CODES.UNKNOWN_ERROR;
|
|
7621
7649
|
}
|
|
7622
7650
|
};
|
|
7623
7651
|
}
|
|
@@ -7659,6 +7687,34 @@ var init_pathResolver = __esm({
|
|
|
7659
7687
|
}
|
|
7660
7688
|
});
|
|
7661
7689
|
|
|
7690
|
+
// packages/tooling/src/utils/typed-file-operations.ts
|
|
7691
|
+
function readPackageJson(filePath) {
|
|
7692
|
+
if (!pathExists(filePath)) {
|
|
7693
|
+
throw new DoNotDevError(
|
|
7694
|
+
`package.json not found: ${filePath}`,
|
|
7695
|
+
DO_NOT_DEV_ERROR_CODES.FILE_NOT_FOUND,
|
|
7696
|
+
{ context: { filePath } }
|
|
7697
|
+
);
|
|
7698
|
+
}
|
|
7699
|
+
const content = readSync(filePath, { format: "json" });
|
|
7700
|
+
if (!content || typeof content !== "object" || !("name" in content)) {
|
|
7701
|
+
throw new DoNotDevError(
|
|
7702
|
+
`Invalid package.json: ${filePath}`,
|
|
7703
|
+
DO_NOT_DEV_ERROR_CODES.CONFIG_INVALID,
|
|
7704
|
+
{ context: { filePath } }
|
|
7705
|
+
);
|
|
7706
|
+
}
|
|
7707
|
+
return content;
|
|
7708
|
+
}
|
|
7709
|
+
var init_typed_file_operations = __esm({
|
|
7710
|
+
"packages/tooling/src/utils/typed-file-operations.ts"() {
|
|
7711
|
+
"use strict";
|
|
7712
|
+
init_utils();
|
|
7713
|
+
init_pathResolver();
|
|
7714
|
+
init_errors();
|
|
7715
|
+
}
|
|
7716
|
+
});
|
|
7717
|
+
|
|
7662
7718
|
// packages/tooling/src/bundler/utils.ts
|
|
7663
7719
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
7664
7720
|
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
|
|
@@ -7702,6 +7758,7 @@ init_dist2();
|
|
|
7702
7758
|
// packages/tooling/src/utils/app-detection.ts
|
|
7703
7759
|
init_utils();
|
|
7704
7760
|
init_pathResolver();
|
|
7761
|
+
init_typed_file_operations();
|
|
7705
7762
|
function detectApps(projectRoot) {
|
|
7706
7763
|
const apps = [];
|
|
7707
7764
|
const appsDir = joinPath(projectRoot, "apps");
|
|
@@ -7722,9 +7779,7 @@ function detectApps(projectRoot) {
|
|
|
7722
7779
|
const packageJsonPath = joinPath(projectRoot, "package.json");
|
|
7723
7780
|
if (pathExists(packageJsonPath)) {
|
|
7724
7781
|
try {
|
|
7725
|
-
const packageJson =
|
|
7726
|
-
format: "json"
|
|
7727
|
-
});
|
|
7782
|
+
const packageJson = readPackageJson(packageJsonPath);
|
|
7728
7783
|
if (packageJson && (packageJson.dependencies?.vite || packageJson.devDependencies?.vite || packageJson.dependencies?.next || packageJson.devDependencies?.next)) {
|
|
7729
7784
|
const pathParts = projectRoot.split(/[/\\]/);
|
|
7730
7785
|
const appName = pathParts[pathParts.length - 1] || "app";
|
|
@@ -7744,10 +7799,10 @@ function analyzeApp(appPath, appName) {
|
|
|
7744
7799
|
if (!pathExists(packageJsonPath)) {
|
|
7745
7800
|
return null;
|
|
7746
7801
|
}
|
|
7747
|
-
let packageJson;
|
|
7802
|
+
let packageJson = null;
|
|
7748
7803
|
try {
|
|
7749
|
-
packageJson =
|
|
7750
|
-
if (!packageJson) {
|
|
7804
|
+
packageJson = readPackageJson(packageJsonPath);
|
|
7805
|
+
if (!packageJson.name) {
|
|
7751
7806
|
return null;
|
|
7752
7807
|
}
|
|
7753
7808
|
} catch {
|
|
@@ -7762,14 +7817,14 @@ function analyzeApp(appPath, appName) {
|
|
|
7762
7817
|
const functionsPath = joinPath(appPath, "functions");
|
|
7763
7818
|
const functionsStat = statSync2(functionsPath);
|
|
7764
7819
|
const hasFunctions = pathExists(functionsPath) && (functionsStat?.isDirectory() ?? false);
|
|
7765
|
-
let
|
|
7820
|
+
let platform2;
|
|
7766
7821
|
if (hasFunctions) {
|
|
7767
7822
|
const firebaseJsonPath = joinPath(functionsPath, "firebase.json");
|
|
7768
7823
|
const vercelJsonPath = joinPath(appPath, "vercel.json");
|
|
7769
7824
|
if (pathExists(firebaseJsonPath)) {
|
|
7770
|
-
|
|
7825
|
+
platform2 = "firebase";
|
|
7771
7826
|
} else if (pathExists(vercelJsonPath)) {
|
|
7772
|
-
|
|
7827
|
+
platform2 = "vercel";
|
|
7773
7828
|
}
|
|
7774
7829
|
}
|
|
7775
7830
|
return {
|
|
@@ -7780,7 +7835,7 @@ function analyzeApp(appPath, appName) {
|
|
|
7780
7835
|
framework,
|
|
7781
7836
|
hasFunctions,
|
|
7782
7837
|
functionsPath: hasFunctions ? functionsPath : void 0,
|
|
7783
|
-
platform
|
|
7838
|
+
platform: platform2
|
|
7784
7839
|
};
|
|
7785
7840
|
}
|
|
7786
7841
|
|
|
@@ -7822,7 +7877,8 @@ async function selectApp(projectRoot, appName) {
|
|
|
7822
7877
|
|
|
7823
7878
|
// packages/tooling/src/apps/dev.ts
|
|
7824
7879
|
init_utils();
|
|
7825
|
-
import {
|
|
7880
|
+
import { spawn, execSync as execSync2 } from "node:child_process";
|
|
7881
|
+
import { platform } from "node:os";
|
|
7826
7882
|
init_cli_output();
|
|
7827
7883
|
init_errors();
|
|
7828
7884
|
init_pathResolver();
|
|
@@ -7838,6 +7894,12 @@ function createAppEnv(appPath) {
|
|
|
7838
7894
|
}
|
|
7839
7895
|
|
|
7840
7896
|
// packages/tooling/src/apps/dev.ts
|
|
7897
|
+
var SIGNAL_EXIT_CODES = {
|
|
7898
|
+
SIGINT: 130,
|
|
7899
|
+
// 128 + 2
|
|
7900
|
+
SIGTERM: 143
|
|
7901
|
+
// 128 + 15
|
|
7902
|
+
};
|
|
7841
7903
|
async function main() {
|
|
7842
7904
|
const args = process.argv.slice(2);
|
|
7843
7905
|
const appName = args[0] && args[0] !== "dev" ? args[0] : void 0;
|
|
@@ -7855,12 +7917,65 @@ async function main() {
|
|
|
7855
7917
|
log.info(`Starting dev server for ${app.name}...
|
|
7856
7918
|
`);
|
|
7857
7919
|
const turboArgs = ["dev", "--filter", app.packageName];
|
|
7858
|
-
const
|
|
7920
|
+
const isWindows = platform() === "win32";
|
|
7921
|
+
const childProcess = spawn("bunx", ["turbo", ...turboArgs], {
|
|
7859
7922
|
stdio: "inherit",
|
|
7860
7923
|
env: createAppEnv(app.path),
|
|
7861
|
-
cwd: projectRoot
|
|
7924
|
+
cwd: projectRoot,
|
|
7925
|
+
shell: isWindows
|
|
7926
|
+
});
|
|
7927
|
+
const cleanup = (signal) => {
|
|
7928
|
+
if (!childProcess.pid) return;
|
|
7929
|
+
log.debug(`Received ${signal}, cleaning up processes...`);
|
|
7930
|
+
if (isWindows) {
|
|
7931
|
+
try {
|
|
7932
|
+
execSync2(`taskkill /F /T /PID ${childProcess.pid}`, {
|
|
7933
|
+
stdio: "ignore",
|
|
7934
|
+
timeout: 2e3
|
|
7935
|
+
});
|
|
7936
|
+
} catch {
|
|
7937
|
+
}
|
|
7938
|
+
} else {
|
|
7939
|
+
try {
|
|
7940
|
+
process.kill(childProcess.pid, signal);
|
|
7941
|
+
} catch {
|
|
7942
|
+
}
|
|
7943
|
+
try {
|
|
7944
|
+
execSync2(`pkill -P ${childProcess.pid}`, {
|
|
7945
|
+
stdio: "ignore",
|
|
7946
|
+
timeout: 1e3
|
|
7947
|
+
});
|
|
7948
|
+
} catch {
|
|
7949
|
+
}
|
|
7950
|
+
}
|
|
7951
|
+
};
|
|
7952
|
+
const signals = ["SIGINT", "SIGTERM"];
|
|
7953
|
+
const handlers = [];
|
|
7954
|
+
for (const signal of signals) {
|
|
7955
|
+
const handler = () => {
|
|
7956
|
+
cleanup(signal);
|
|
7957
|
+
handlers.forEach((h2) => h2());
|
|
7958
|
+
process.exit(SIGNAL_EXIT_CODES[signal] ?? 130);
|
|
7959
|
+
};
|
|
7960
|
+
process.on(signal, handler);
|
|
7961
|
+
handlers.push(() => process.removeListener(signal, handler));
|
|
7962
|
+
}
|
|
7963
|
+
return new Promise((resolve4) => {
|
|
7964
|
+
childProcess.on("exit", (code, signal) => {
|
|
7965
|
+
handlers.forEach((h2) => h2());
|
|
7966
|
+
if (signal) {
|
|
7967
|
+
log.debug(`Process killed by signal: ${signal}`);
|
|
7968
|
+
resolve4(SIGNAL_EXIT_CODES[signal] ?? 130);
|
|
7969
|
+
} else {
|
|
7970
|
+
resolve4(code ?? 0);
|
|
7971
|
+
}
|
|
7972
|
+
});
|
|
7973
|
+
childProcess.on("error", (error2) => {
|
|
7974
|
+
handlers.forEach((h2) => h2());
|
|
7975
|
+
log.error(`Failed to start dev server: ${error2.message}`);
|
|
7976
|
+
resolve4(1);
|
|
7977
|
+
});
|
|
7862
7978
|
});
|
|
7863
|
-
return result.status || 0;
|
|
7864
7979
|
}
|
|
7865
7980
|
export {
|
|
7866
7981
|
main
|
package/dist/bin/commands/emu.js
CHANGED
|
@@ -7594,11 +7594,39 @@ var init_PathResolver = __esm({
|
|
|
7594
7594
|
});
|
|
7595
7595
|
|
|
7596
7596
|
// packages/tooling/src/utils/errors.ts
|
|
7597
|
-
var DoNotDevError;
|
|
7597
|
+
var DO_NOT_DEV_ERROR_CODES, DoNotDevError;
|
|
7598
7598
|
var init_errors = __esm({
|
|
7599
7599
|
"packages/tooling/src/utils/errors.ts"() {
|
|
7600
7600
|
"use strict";
|
|
7601
7601
|
init_utils();
|
|
7602
|
+
DO_NOT_DEV_ERROR_CODES = {
|
|
7603
|
+
CONFIGURATION_ERROR: "configuration-error",
|
|
7604
|
+
CONFIG_NOT_FOUND: "config-not-found",
|
|
7605
|
+
CONFIG_INVALID: "config-invalid",
|
|
7606
|
+
PATH_RESOLUTION_ERROR: "path-resolution-error",
|
|
7607
|
+
FILE_OPERATION_ERROR: "file-operation-error",
|
|
7608
|
+
FILE_NOT_FOUND: "file-not-found",
|
|
7609
|
+
PERMISSION_DENIED: "permission-denied",
|
|
7610
|
+
GENERATION_ERROR: "generation-error",
|
|
7611
|
+
TEMPLATE_ERROR: "template-error",
|
|
7612
|
+
TEMPLATE_NOT_FOUND: "template-not-found",
|
|
7613
|
+
CLI_EXECUTION_ERROR: "cli-execution-error",
|
|
7614
|
+
COMMAND_NOT_FOUND: "command-not-found",
|
|
7615
|
+
COMMAND_FAILED: "command-failed",
|
|
7616
|
+
VALIDATION_ERROR: "validation-error",
|
|
7617
|
+
SCHEMA_ERROR: "schema-error",
|
|
7618
|
+
DEPENDENCY_ERROR: "dependency-error",
|
|
7619
|
+
DEPENDENCY_NOT_FOUND: "dependency-not-found",
|
|
7620
|
+
DEPENDENCY_VERSION_ERROR: "dependency-version-error",
|
|
7621
|
+
INVALID_ARGUMENT: "invalid-argument",
|
|
7622
|
+
MISSING_ARGUMENT: "missing-argument",
|
|
7623
|
+
MISSING_PROJECT_ID: "missing-project-id",
|
|
7624
|
+
FIREBASE_CLI_ERROR: "firebase-cli-error",
|
|
7625
|
+
DEPLOYMENT_FAILED: "deployment-failed",
|
|
7626
|
+
OPERATION_CANCELLED: "operation-cancelled",
|
|
7627
|
+
TIMEOUT_ERROR: "timeout-error",
|
|
7628
|
+
UNKNOWN_ERROR: "unknown-error"
|
|
7629
|
+
};
|
|
7602
7630
|
DoNotDevError = class _DoNotDevError extends Error {
|
|
7603
7631
|
/** The error code categorizing this error */
|
|
7604
7632
|
code;
|
|
@@ -7618,7 +7646,7 @@ var init_errors = __esm({
|
|
|
7618
7646
|
* @param {Record<string, any>} [options.context] - Additional context data
|
|
7619
7647
|
* @param {boolean} [options.displayable=true] - Whether this error should be displayed to the user
|
|
7620
7648
|
*/
|
|
7621
|
-
constructor(message, code =
|
|
7649
|
+
constructor(message, code = DO_NOT_DEV_ERROR_CODES.UNKNOWN_ERROR, options) {
|
|
7622
7650
|
super(message);
|
|
7623
7651
|
this.name = "DoNotDevError";
|
|
7624
7652
|
this.code = code;
|
|
@@ -7649,7 +7677,7 @@ var init_errors = __esm({
|
|
|
7649
7677
|
* @param {boolean} [options.displayable=true] - Whether this error should be displayed to the user
|
|
7650
7678
|
* @returns {DoNotDevError} New DoNotDev error wrapping the original
|
|
7651
7679
|
*/
|
|
7652
|
-
static from(error2, context, code =
|
|
7680
|
+
static from(error2, context, code = DO_NOT_DEV_ERROR_CODES.UNKNOWN_ERROR, options) {
|
|
7653
7681
|
if (!(error2 instanceof Error)) {
|
|
7654
7682
|
return new _DoNotDevError(
|
|
7655
7683
|
`Unknown error: ${String(error2)}`,
|
|
@@ -7686,21 +7714,21 @@ var init_errors = __esm({
|
|
|
7686
7714
|
}
|
|
7687
7715
|
const message = error2.message.toLowerCase();
|
|
7688
7716
|
if (error2.name === "ValidationError" || message.includes("validation")) {
|
|
7689
|
-
return
|
|
7717
|
+
return DO_NOT_DEV_ERROR_CODES.VALIDATION_ERROR;
|
|
7690
7718
|
}
|
|
7691
7719
|
if (message.includes("not found") || message.includes("no such file")) {
|
|
7692
|
-
return
|
|
7720
|
+
return DO_NOT_DEV_ERROR_CODES.FILE_NOT_FOUND;
|
|
7693
7721
|
}
|
|
7694
7722
|
if (message.includes("permission") || message.includes("access denied")) {
|
|
7695
|
-
return
|
|
7723
|
+
return DO_NOT_DEV_ERROR_CODES.PERMISSION_DENIED;
|
|
7696
7724
|
}
|
|
7697
7725
|
if (message.includes("timeout") || message.includes("timed out")) {
|
|
7698
|
-
return
|
|
7726
|
+
return DO_NOT_DEV_ERROR_CODES.TIMEOUT_ERROR;
|
|
7699
7727
|
}
|
|
7700
7728
|
if (message.includes("dependency") || message.includes("module not found")) {
|
|
7701
|
-
return
|
|
7729
|
+
return DO_NOT_DEV_ERROR_CODES.DEPENDENCY_ERROR;
|
|
7702
7730
|
}
|
|
7703
|
-
return
|
|
7731
|
+
return DO_NOT_DEV_ERROR_CODES.UNKNOWN_ERROR;
|
|
7704
7732
|
}
|
|
7705
7733
|
};
|
|
7706
7734
|
}
|
|
@@ -7743,6 +7771,52 @@ var init_pathResolver = __esm({
|
|
|
7743
7771
|
}
|
|
7744
7772
|
});
|
|
7745
7773
|
|
|
7774
|
+
// packages/tooling/src/utils/typed-file-operations.ts
|
|
7775
|
+
function readFirebaseJson(filePath) {
|
|
7776
|
+
if (!pathExists(filePath)) {
|
|
7777
|
+
throw new DoNotDevError(
|
|
7778
|
+
`firebase.json not found: ${filePath}`,
|
|
7779
|
+
DO_NOT_DEV_ERROR_CODES.FILE_NOT_FOUND,
|
|
7780
|
+
{ context: { filePath } }
|
|
7781
|
+
);
|
|
7782
|
+
}
|
|
7783
|
+
const content = readSync(filePath, { format: "json" });
|
|
7784
|
+
if (!content || typeof content !== "object") {
|
|
7785
|
+
throw new DoNotDevError(
|
|
7786
|
+
`Invalid firebase.json: ${filePath}`,
|
|
7787
|
+
DO_NOT_DEV_ERROR_CODES.CONFIG_INVALID,
|
|
7788
|
+
{ context: { filePath } }
|
|
7789
|
+
);
|
|
7790
|
+
}
|
|
7791
|
+
return content;
|
|
7792
|
+
}
|
|
7793
|
+
function readPackageJson(filePath) {
|
|
7794
|
+
if (!pathExists(filePath)) {
|
|
7795
|
+
throw new DoNotDevError(
|
|
7796
|
+
`package.json not found: ${filePath}`,
|
|
7797
|
+
DO_NOT_DEV_ERROR_CODES.FILE_NOT_FOUND,
|
|
7798
|
+
{ context: { filePath } }
|
|
7799
|
+
);
|
|
7800
|
+
}
|
|
7801
|
+
const content = readSync(filePath, { format: "json" });
|
|
7802
|
+
if (!content || typeof content !== "object" || !("name" in content)) {
|
|
7803
|
+
throw new DoNotDevError(
|
|
7804
|
+
`Invalid package.json: ${filePath}`,
|
|
7805
|
+
DO_NOT_DEV_ERROR_CODES.CONFIG_INVALID,
|
|
7806
|
+
{ context: { filePath } }
|
|
7807
|
+
);
|
|
7808
|
+
}
|
|
7809
|
+
return content;
|
|
7810
|
+
}
|
|
7811
|
+
var init_typed_file_operations = __esm({
|
|
7812
|
+
"packages/tooling/src/utils/typed-file-operations.ts"() {
|
|
7813
|
+
"use strict";
|
|
7814
|
+
init_utils();
|
|
7815
|
+
init_pathResolver();
|
|
7816
|
+
init_errors();
|
|
7817
|
+
}
|
|
7818
|
+
});
|
|
7819
|
+
|
|
7746
7820
|
// packages/tooling/src/bundler/utils.ts
|
|
7747
7821
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
7748
7822
|
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
|
|
@@ -7770,6 +7844,33 @@ var init_utils = __esm({
|
|
|
7770
7844
|
}
|
|
7771
7845
|
});
|
|
7772
7846
|
|
|
7847
|
+
// packages/tooling/src/utils/cli-input.ts
|
|
7848
|
+
async function askForMultiSelection(message, choices, defaultIndices = []) {
|
|
7849
|
+
const options = choices.map((choice) => ({
|
|
7850
|
+
value: choice.value,
|
|
7851
|
+
label: choice.title,
|
|
7852
|
+
hint: choice.hint
|
|
7853
|
+
}));
|
|
7854
|
+
const initialValues = defaultIndices.map((i) => choices[i]?.value).filter(Boolean);
|
|
7855
|
+
const result = await fe({
|
|
7856
|
+
message,
|
|
7857
|
+
options,
|
|
7858
|
+
initialValues: initialValues.length > 0 ? initialValues : void 0
|
|
7859
|
+
});
|
|
7860
|
+
if (pD(result)) {
|
|
7861
|
+
xe("Operation cancelled.");
|
|
7862
|
+
process.exit(0);
|
|
7863
|
+
}
|
|
7864
|
+
return result;
|
|
7865
|
+
}
|
|
7866
|
+
var init_cli_input = __esm({
|
|
7867
|
+
"packages/tooling/src/utils/cli-input.ts"() {
|
|
7868
|
+
"use strict";
|
|
7869
|
+
init_utils();
|
|
7870
|
+
init_dist2();
|
|
7871
|
+
}
|
|
7872
|
+
});
|
|
7873
|
+
|
|
7773
7874
|
// packages/cli/src/bin/commands/emu.ts
|
|
7774
7875
|
init_utils();
|
|
7775
7876
|
|
|
@@ -7786,6 +7887,7 @@ init_dist2();
|
|
|
7786
7887
|
// packages/tooling/src/utils/app-detection.ts
|
|
7787
7888
|
init_utils();
|
|
7788
7889
|
init_pathResolver();
|
|
7890
|
+
init_typed_file_operations();
|
|
7789
7891
|
function detectApps(projectRoot) {
|
|
7790
7892
|
const apps = [];
|
|
7791
7893
|
const appsDir = joinPath(projectRoot, "apps");
|
|
@@ -7806,9 +7908,7 @@ function detectApps(projectRoot) {
|
|
|
7806
7908
|
const packageJsonPath = joinPath(projectRoot, "package.json");
|
|
7807
7909
|
if (pathExists(packageJsonPath)) {
|
|
7808
7910
|
try {
|
|
7809
|
-
const packageJson =
|
|
7810
|
-
format: "json"
|
|
7811
|
-
});
|
|
7911
|
+
const packageJson = readPackageJson(packageJsonPath);
|
|
7812
7912
|
if (packageJson && (packageJson.dependencies?.vite || packageJson.devDependencies?.vite || packageJson.dependencies?.next || packageJson.devDependencies?.next)) {
|
|
7813
7913
|
const pathParts = projectRoot.split(/[/\\]/);
|
|
7814
7914
|
const appName = pathParts[pathParts.length - 1] || "app";
|
|
@@ -7828,10 +7928,10 @@ function analyzeApp(appPath, appName) {
|
|
|
7828
7928
|
if (!pathExists(packageJsonPath)) {
|
|
7829
7929
|
return null;
|
|
7830
7930
|
}
|
|
7831
|
-
let packageJson;
|
|
7931
|
+
let packageJson = null;
|
|
7832
7932
|
try {
|
|
7833
|
-
packageJson =
|
|
7834
|
-
if (!packageJson) {
|
|
7933
|
+
packageJson = readPackageJson(packageJsonPath);
|
|
7934
|
+
if (!packageJson.name) {
|
|
7835
7935
|
return null;
|
|
7836
7936
|
}
|
|
7837
7937
|
} catch {
|
|
@@ -7846,14 +7946,14 @@ function analyzeApp(appPath, appName) {
|
|
|
7846
7946
|
const functionsPath = joinPath(appPath, "functions");
|
|
7847
7947
|
const functionsStat = statSync2(functionsPath);
|
|
7848
7948
|
const hasFunctions = pathExists(functionsPath) && (functionsStat?.isDirectory() ?? false);
|
|
7849
|
-
let
|
|
7949
|
+
let platform2;
|
|
7850
7950
|
if (hasFunctions) {
|
|
7851
7951
|
const firebaseJsonPath = joinPath(functionsPath, "firebase.json");
|
|
7852
7952
|
const vercelJsonPath = joinPath(appPath, "vercel.json");
|
|
7853
7953
|
if (pathExists(firebaseJsonPath)) {
|
|
7854
|
-
|
|
7954
|
+
platform2 = "firebase";
|
|
7855
7955
|
} else if (pathExists(vercelJsonPath)) {
|
|
7856
|
-
|
|
7956
|
+
platform2 = "vercel";
|
|
7857
7957
|
}
|
|
7858
7958
|
}
|
|
7859
7959
|
return {
|
|
@@ -7864,7 +7964,7 @@ function analyzeApp(appPath, appName) {
|
|
|
7864
7964
|
framework,
|
|
7865
7965
|
hasFunctions,
|
|
7866
7966
|
functionsPath: hasFunctions ? functionsPath : void 0,
|
|
7867
|
-
platform
|
|
7967
|
+
platform: platform2
|
|
7868
7968
|
};
|
|
7869
7969
|
}
|
|
7870
7970
|
|
|
@@ -7904,28 +8004,6 @@ async function selectApp(projectRoot, appName) {
|
|
|
7904
8004
|
return apps.find((a) => a.name === selected) || null;
|
|
7905
8005
|
}
|
|
7906
8006
|
|
|
7907
|
-
// packages/tooling/src/utils/cli-input.ts
|
|
7908
|
-
init_utils();
|
|
7909
|
-
init_dist2();
|
|
7910
|
-
async function askForMultiSelection(message, choices, defaultIndices = []) {
|
|
7911
|
-
const options = choices.map((choice) => ({
|
|
7912
|
-
value: choice.value,
|
|
7913
|
-
label: choice.title,
|
|
7914
|
-
hint: choice.hint
|
|
7915
|
-
}));
|
|
7916
|
-
const initialValues = defaultIndices.map((i) => choices[i]?.value).filter(Boolean);
|
|
7917
|
-
const result = await fe({
|
|
7918
|
-
message,
|
|
7919
|
-
options,
|
|
7920
|
-
initialValues: initialValues.length > 0 ? initialValues : void 0
|
|
7921
|
-
});
|
|
7922
|
-
if (pD(result)) {
|
|
7923
|
-
xe("Operation cancelled.");
|
|
7924
|
-
process.exit(0);
|
|
7925
|
-
}
|
|
7926
|
-
return result;
|
|
7927
|
-
}
|
|
7928
|
-
|
|
7929
8007
|
// packages/tooling/src/utils/spawn-utils.ts
|
|
7930
8008
|
init_utils();
|
|
7931
8009
|
import { spawnSync, execSync } from "node:child_process";
|
|
@@ -7970,16 +8048,24 @@ function createEmulatorEnv(appPath, framework = "vite", options) {
|
|
|
7970
8048
|
|
|
7971
8049
|
// packages/tooling/src/apps/emu.ts
|
|
7972
8050
|
init_utils();
|
|
7973
|
-
import {
|
|
8051
|
+
import {
|
|
8052
|
+
spawn,
|
|
8053
|
+
spawnSync as spawnSync2,
|
|
8054
|
+
execSync as execSync2
|
|
8055
|
+
} from "node:child_process";
|
|
8056
|
+
import { platform } from "node:os";
|
|
8057
|
+
init_cli_input();
|
|
7974
8058
|
init_cli_output();
|
|
7975
8059
|
init_errors();
|
|
7976
8060
|
init_pathResolver();
|
|
7977
8061
|
init_pathResolver();
|
|
8062
|
+
init_typed_file_operations();
|
|
7978
8063
|
function discoverFirebaseProjectId(appPath) {
|
|
7979
8064
|
const firebasercPath = joinPath(appPath, ".firebaserc");
|
|
7980
8065
|
if (pathExists(firebasercPath)) {
|
|
7981
8066
|
try {
|
|
7982
|
-
const
|
|
8067
|
+
const firebasercRaw = readSync(firebasercPath, { format: "json" });
|
|
8068
|
+
const firebaserc = firebasercRaw && typeof firebasercRaw === "object" ? firebasercRaw : null;
|
|
7983
8069
|
if (firebaserc?.projects?.default) {
|
|
7984
8070
|
return firebaserc.projects.default;
|
|
7985
8071
|
}
|
|
@@ -8014,12 +8100,18 @@ function killPorts(ports) {
|
|
|
8014
8100
|
}
|
|
8015
8101
|
} else {
|
|
8016
8102
|
try {
|
|
8017
|
-
const
|
|
8103
|
+
const output = execSync2(`lsof -ti:${port}`, {
|
|
8018
8104
|
encoding: "utf-8"
|
|
8019
8105
|
}).trim();
|
|
8020
|
-
if (
|
|
8021
|
-
|
|
8022
|
-
|
|
8106
|
+
if (output) {
|
|
8107
|
+
const pids = output.split("\n").filter(Boolean);
|
|
8108
|
+
for (const pid of pids) {
|
|
8109
|
+
try {
|
|
8110
|
+
execSync2(`kill -9 ${pid}`, { stdio: "ignore" });
|
|
8111
|
+
log.debug(`Killed process ${pid} on port ${port}`);
|
|
8112
|
+
} catch {
|
|
8113
|
+
}
|
|
8114
|
+
}
|
|
8023
8115
|
}
|
|
8024
8116
|
} catch {
|
|
8025
8117
|
}
|
|
@@ -8206,8 +8298,10 @@ FIREBASE_AUTH_EMULATOR_HOST=${authEmulatorHost}
|
|
|
8206
8298
|
let emulatorConfig = null;
|
|
8207
8299
|
if (pathExists(appFirebaseJson)) {
|
|
8208
8300
|
try {
|
|
8209
|
-
const firebaseConfig =
|
|
8210
|
-
|
|
8301
|
+
const firebaseConfig = readFirebaseJson(appFirebaseJson);
|
|
8302
|
+
if (firebaseConfig.emulators) {
|
|
8303
|
+
emulatorConfig = firebaseConfig.emulators;
|
|
8304
|
+
}
|
|
8211
8305
|
} catch {
|
|
8212
8306
|
}
|
|
8213
8307
|
}
|
|
@@ -8244,7 +8338,7 @@ FIREBASE_AUTH_EMULATOR_HOST=${authEmulatorHost}
|
|
|
8244
8338
|
const concurrentlyArgs = [
|
|
8245
8339
|
"--kill-others-on-fail",
|
|
8246
8340
|
"--prefix-colors",
|
|
8247
|
-
"cyan,green,yellow",
|
|
8341
|
+
useStripe ? "cyan,green,yellow" : "cyan,green",
|
|
8248
8342
|
"--prefix",
|
|
8249
8343
|
"[{name}]",
|
|
8250
8344
|
"--names",
|
|
@@ -8262,15 +8356,78 @@ FIREBASE_AUTH_EMULATOR_HOST=${authEmulatorHost}
|
|
|
8262
8356
|
log.info(" stripe trigger checkout.session.completed");
|
|
8263
8357
|
log.info("");
|
|
8264
8358
|
}
|
|
8265
|
-
const
|
|
8266
|
-
|
|
8267
|
-
|
|
8268
|
-
|
|
8269
|
-
|
|
8270
|
-
|
|
8271
|
-
|
|
8359
|
+
const isWindows = platform() === "win32";
|
|
8360
|
+
const childProcess = spawn(
|
|
8361
|
+
"bunx",
|
|
8362
|
+
["concurrently", ...concurrentlyArgs],
|
|
8363
|
+
{
|
|
8364
|
+
stdio: "inherit",
|
|
8365
|
+
env: createEmulatorEnv(app.path, app.framework, {
|
|
8366
|
+
useEmulatorAuth: useAuth,
|
|
8367
|
+
useEmulatorFirestore: useFirestore
|
|
8368
|
+
}),
|
|
8369
|
+
cwd: app.path,
|
|
8370
|
+
shell: isWindows
|
|
8371
|
+
}
|
|
8372
|
+
);
|
|
8373
|
+
const SIGNAL_EXIT_CODES = {
|
|
8374
|
+
SIGINT: 130,
|
|
8375
|
+
// 128 + 2
|
|
8376
|
+
SIGTERM: 143
|
|
8377
|
+
// 128 + 15
|
|
8378
|
+
};
|
|
8379
|
+
const cleanup = (signal) => {
|
|
8380
|
+
if (!childProcess.pid) return;
|
|
8381
|
+
log.debug(`Received ${signal}, cleaning up processes...`);
|
|
8382
|
+
if (isWindows) {
|
|
8383
|
+
try {
|
|
8384
|
+
execSync2(`taskkill /F /T /PID ${childProcess.pid}`, {
|
|
8385
|
+
stdio: "ignore",
|
|
8386
|
+
timeout: 2e3
|
|
8387
|
+
});
|
|
8388
|
+
} catch {
|
|
8389
|
+
}
|
|
8390
|
+
} else {
|
|
8391
|
+
try {
|
|
8392
|
+
process.kill(childProcess.pid, signal);
|
|
8393
|
+
} catch {
|
|
8394
|
+
}
|
|
8395
|
+
try {
|
|
8396
|
+
execSync2(`pkill -P ${childProcess.pid}`, {
|
|
8397
|
+
stdio: "ignore",
|
|
8398
|
+
timeout: 1e3
|
|
8399
|
+
});
|
|
8400
|
+
} catch {
|
|
8401
|
+
}
|
|
8402
|
+
}
|
|
8403
|
+
};
|
|
8404
|
+
const signals = ["SIGINT", "SIGTERM"];
|
|
8405
|
+
const handlers = [];
|
|
8406
|
+
for (const signal of signals) {
|
|
8407
|
+
const handler = () => {
|
|
8408
|
+
cleanup(signal);
|
|
8409
|
+
handlers.forEach((h2) => h2());
|
|
8410
|
+
process.exit(SIGNAL_EXIT_CODES[signal] ?? 130);
|
|
8411
|
+
};
|
|
8412
|
+
process.on(signal, handler);
|
|
8413
|
+
handlers.push(() => process.removeListener(signal, handler));
|
|
8414
|
+
}
|
|
8415
|
+
return new Promise((resolve4) => {
|
|
8416
|
+
childProcess.on("exit", (code, signal) => {
|
|
8417
|
+
handlers.forEach((h2) => h2());
|
|
8418
|
+
if (signal) {
|
|
8419
|
+
log.debug(`Process killed by signal: ${signal}`);
|
|
8420
|
+
resolve4(SIGNAL_EXIT_CODES[signal] ?? 130);
|
|
8421
|
+
} else {
|
|
8422
|
+
resolve4(code ?? 0);
|
|
8423
|
+
}
|
|
8424
|
+
});
|
|
8425
|
+
childProcess.on("error", (error2) => {
|
|
8426
|
+
handlers.forEach((h2) => h2());
|
|
8427
|
+
log.error(`Failed to start emulators: ${error2.message}`);
|
|
8428
|
+
resolve4(1);
|
|
8429
|
+
});
|
|
8272
8430
|
});
|
|
8273
|
-
return result.status || 0;
|
|
8274
8431
|
}
|
|
8275
8432
|
export {
|
|
8276
8433
|
main
|