@rebasepro/cli 0.13.1-canary.g18cfeb7 → 0.13.1-canary.g249daa1

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.
@@ -68,6 +68,35 @@ export declare function formatCdTarget(cwd: string, targetDirectory: string): st
68
68
  * triggering the non-TTY error. */
69
69
  export declare function printInitHelp(): void;
70
70
  export declare function createRebaseApp(rawArgs: string[]): Promise<void>;
71
+ /**
72
+ * Whether `port` is free — on the wildcard address *and* on both loopback addresses.
73
+ *
74
+ * All three, because on macOS/BSD a successful bind does not mean the port is
75
+ * unused. Sockets carry `SO_REUSEADDR` (Node sets it), under which a wildcard
76
+ * bind and a specific-address bind on the same port do not conflict — in either
77
+ * direction. So each probe alone has a blind spot, and they are different ones:
78
+ *
79
+ * - **Wildcard only** (what this used to do) misses a server bound to
80
+ * `127.0.0.1` and `[::1]` — a Homebrew or Postgres.app install, i.e. most
81
+ * developer machines. 5432 was reported free while it was already serving
82
+ * another project's database. Docker then published `*:5432` for the same
83
+ * reason and the container started cleanly, with no "port already allocated"
84
+ * error anywhere to hint at the collision. `DATABASE_URL` pointed at
85
+ * `localhost:5432`, `localhost` resolves to `::1` first, and every command
86
+ * reported success while reading and writing the *pre-existing* database — a
87
+ * `db push` would have created tables, roles and RLS policies inside it.
88
+ *
89
+ * - **Loopback only** misses the opposite case: Docker Desktop publishes a
90
+ * container's port on `*`, and a specific-address bind succeeds right past it.
91
+ * That port is free to probe and unusable to publish, so `docker compose up -d
92
+ * db` fails on "Bind for 0.0.0.0:PORT failed: port is already allocated" —
93
+ * loudly, but only after the project has been generated around the bad port.
94
+ *
95
+ * Requiring all three costs three sockets and leaves neither gap. The wildcard
96
+ * bind is the one the container itself has to make; the loopback binds are the
97
+ * addresses `DATABASE_URL` will actually name.
98
+ */
99
+ export declare function isPortAvailable(port: number): Promise<boolean>;
71
100
  /**
72
101
  * The runtime image tag to pin, given the version of the CLI doing the scaffolding.
73
102
  *
@@ -62,6 +62,53 @@ export declare function foldableApps(manifest: FoldableManifest): {
62
62
  * evidence of a misbuild.
63
63
  */
64
64
  export declare function assertBuiltForPath(indexHtml: string, basePath: string, appName: string): void;
65
+ /**
66
+ * The environment every static app is built with, wherever that build is driven from.
67
+ *
68
+ * Shared because there are two drivers — `foldFrontendIntoBundle` here, and
69
+ * `buildAssetApp` in `build.ts` for a standalone `type: "static"` app — and they
70
+ * had already drifted: the path variables were duplicated into both, so a fix
71
+ * applied to one shipped a bundle built the old way from the other. One function
72
+ * makes that impossible rather than merely unlikely.
73
+ *
74
+ * ## REBASE_APP_*
75
+ *
76
+ * The declared path is a build-time input, not only a serving concern: Vite
77
+ * reads `base` from REBASE_APP_BASE, and the trailing slash is that field's
78
+ * convention. See `assertBuiltForPath`.
79
+ *
80
+ * ## NODE_ENV
81
+ *
82
+ * A built app is a production artifact by construction, so build it as one. Not
83
+ * a formality: the scaffold's `.env` carries `NODE_ENV=development` for the dev
84
+ * backend, and Vite's `loadEnv` promotes a `NODE_ENV` found in an env file into
85
+ * the build unless the environment already sets one. So `rebase build` and
86
+ * `rebase cloud deploy` shipped a *development* bundle — `import.meta.env.DEV
87
+ * === true`, development React, dev-only branches live — from commands whose
88
+ * whole purpose is to produce something deployable. Setting it here is what
89
+ * closes it: Vite consults the env file's NODE_ENV only when `process.env`
90
+ * has none.
91
+ *
92
+ * ## VITE_API_URL
93
+ *
94
+ * An app served by the backend it talks to has its API on its own origin by
95
+ * construction, so a baked-in absolute URL can only be wrong. It was: that same
96
+ * `.env` carries `VITE_API_URL=http://localhost:3001` and
97
+ * `frontend/vite.config.ts` reads the project root via `envDir: ".."`, so a
98
+ * stock deploy shipped a site whose every request went to whoever ran the build
99
+ * — passing every server-side health check on the way out. Blanking it here
100
+ * fixes the bundle even for a project whose `.env` predates the `init` fix, or
101
+ * was written by hand. Empty is the right value rather than a missing one: the
102
+ * client falls back to `window.location.origin`, which keeps working when a
103
+ * custom domain is added.
104
+ *
105
+ * Vite prioritises `process.env.VITE_*` over `.env` files, so an explicit
106
+ * `VITE_API_URL=https://api.example.com rebase cloud deploy` still wins — the
107
+ * cross-origin escape hatch stays open, it just has to be deliberate. Nothing on
108
+ * this path loads the project `.env` into `process.env`, so a value inherited
109
+ * here really was set by the caller.
110
+ */
111
+ export declare function staticBuildEnv(appPath: string, appName: string): Record<string, string>;
65
112
  /**
66
113
  * Build the project's static apps and fold them into the backend bundle.
67
114
  *
package/dist/index.es.js CHANGED
@@ -13,9 +13,9 @@ import { execSync, spawn, spawnSync } from "child_process";
13
13
  import os from "os";
14
14
  import { createRebaseClient } from "@rebasepro/client";
15
15
  import dotenv from "dotenv";
16
- import { createRequire } from "module";
17
16
  import { BUNDLE_FORMAT_VERSION, DEFAULT_DATA_SOURCE_KEY, RUNTIME_CONTRACT_VERSION, computeSchemaVersion, deserializeCollections, findStorageSuffixCollision, getDataSourceCapabilities, normalizeStorageSources, storageEnvSuffix } from "@rebasepro/types";
18
17
  import { generateSDK } from "@rebasepro/codegen";
18
+ import { createRequire } from "module";
19
19
  //#region src/utils/package-manager.ts
20
20
  /**
21
21
  * Package manager detection and command abstraction.
@@ -978,13 +978,35 @@ function sanitize(properties) {
978
978
  }
979
979
  return out;
980
980
  }
981
+ /**
982
+ * The CLI's own version, read by walking up to this package's manifest.
983
+ *
984
+ * The obvious `require("../../package.json")` was wrong everywhere, not only on
985
+ * one install path: `vite build` bundles this module into `dist/index.es.js`, so
986
+ * the specifier resolves relative to `<pkg>/dist/` and lands on
987
+ * `<parent-of-pkg>/package.json` — a file that does not exist under npm, pnpm or
988
+ * the monorepo. Every event ever sent carried `cliVersion: "unknown"`, which is
989
+ * the one field that makes the rest of a payload interpretable.
990
+ *
991
+ * So walk up and check the manifest's `name` rather than counting directory
992
+ * levels: the count differs between `src/telemetry/` and the bundled `dist/`,
993
+ * and a wrong count fails silently by finding *some* package.json — the nearest
994
+ * dependency's, under a hoisted layout. Matching the name cannot do that.
995
+ */
981
996
  function cliVersion() {
982
997
  try {
983
- const pkg = createRequire(import.meta.url)("../../package.json");
984
- return typeof pkg?.version === "string" ? pkg.version : "unknown";
985
- } catch {
986
- return "unknown";
987
- }
998
+ let dir = path.dirname(fileURLToPath(import.meta.url));
999
+ const root = path.parse(dir).root;
1000
+ while (dir && dir !== root) {
1001
+ const manifest = path.join(dir, "package.json");
1002
+ if (fs.existsSync(manifest)) {
1003
+ const pkg = JSON.parse(fs.readFileSync(manifest, "utf-8"));
1004
+ if (pkg?.name === "@rebasepro/cli" && typeof pkg.version === "string" && pkg.version) return pkg.version;
1005
+ }
1006
+ dir = path.dirname(dir);
1007
+ }
1008
+ } catch {}
1009
+ return "unknown";
988
1010
  }
989
1011
  function buildEvent(event, properties, identity) {
990
1012
  return {
@@ -1635,6 +1657,49 @@ async function linkScaffoldToCloud(options) {
1635
1657
  console.warn(chalk.yellow(` ${linkLater}`));
1636
1658
  }
1637
1659
  }
1660
+ /**
1661
+ * Make the initial commit, after everything that writes into the project has run.
1662
+ *
1663
+ * It used to happen immediately after `git init`, which is before dependency
1664
+ * installation and before introspection — so `init --git --install` ended on a
1665
+ * dirty tree whose only untracked file was `pnpm-lock.yaml`. A lockfile is
1666
+ * precisely the thing that should be in a project's first commit, and a brand
1667
+ * new scaffold whose first `git status` is dirty invites the reader to conclude
1668
+ * the lockfile is deliberately ignored and never commit it at all.
1669
+ *
1670
+ * Introspection has the same shape: it generates `config/collections` and
1671
+ * `schema.generated.ts`, which belong in the commit describing the scaffold that
1672
+ * produced them.
1673
+ *
1674
+ * `git init` stays where it was. Creating the repository early costs nothing and
1675
+ * means a failed install still leaves the user a repository to commit into.
1676
+ */
1677
+ async function commitScaffold(targetDirectory) {
1678
+ try {
1679
+ await execa("git", ["add", "-A"], { cwd: targetDirectory });
1680
+ let identity = {};
1681
+ try {
1682
+ await execa("git", ["config", "user.email"], { cwd: targetDirectory });
1683
+ } catch {
1684
+ identity = {
1685
+ GIT_AUTHOR_NAME: "Rebase",
1686
+ GIT_AUTHOR_EMAIL: "noreply@rebase.pro",
1687
+ GIT_COMMITTER_NAME: "Rebase",
1688
+ GIT_COMMITTER_EMAIL: "noreply@rebase.pro"
1689
+ };
1690
+ }
1691
+ await execa("git", [
1692
+ "commit",
1693
+ "-m",
1694
+ "Initial commit from Rebase"
1695
+ ], {
1696
+ cwd: targetDirectory,
1697
+ env: identity
1698
+ });
1699
+ } catch {
1700
+ console.warn(chalk.yellow(" Warning: Failed to create the initial commit"));
1701
+ }
1702
+ }
1638
1703
  async function createProject$1(options) {
1639
1704
  const startedAt = Date.now();
1640
1705
  if (fs.existsSync(options.targetDirectory)) {
@@ -1674,6 +1739,7 @@ async function createProject$1(options) {
1674
1739
  await applyHeadless(options.targetDirectory, options.headless);
1675
1740
  await replacePlaceholders(options);
1676
1741
  await configureEnvFile(options.targetDirectory, options.databaseUrl);
1742
+ let gitInitialized = false;
1677
1743
  if (options.git) {
1678
1744
  console.log(chalk.gray(" Initializing git repository..."));
1679
1745
  try {
@@ -1685,26 +1751,7 @@ async function createProject$1(options) {
1685
1751
  "refs/heads/main"
1686
1752
  ], { cwd: options.targetDirectory });
1687
1753
  } catch {}
1688
- await execa("git", ["add", "-A"], { cwd: options.targetDirectory });
1689
- let identity = {};
1690
- try {
1691
- await execa("git", ["config", "user.email"], { cwd: options.targetDirectory });
1692
- } catch {
1693
- identity = {
1694
- GIT_AUTHOR_NAME: "Rebase",
1695
- GIT_AUTHOR_EMAIL: "noreply@rebase.pro",
1696
- GIT_COMMITTER_NAME: "Rebase",
1697
- GIT_COMMITTER_EMAIL: "noreply@rebase.pro"
1698
- };
1699
- }
1700
- await execa("git", [
1701
- "commit",
1702
- "-m",
1703
- "Initial commit from Rebase"
1704
- ], {
1705
- cwd: options.targetDirectory,
1706
- env: identity
1707
- });
1754
+ gitInitialized = true;
1708
1755
  } catch {
1709
1756
  console.warn(chalk.yellow(" Warning: Failed to initialize git repository"));
1710
1757
  }
@@ -1761,6 +1808,7 @@ async function createProject$1(options) {
1761
1808
  console.warn(chalk.yellow(` Run \`${installCmd.join(" ")}\` then \`${execCmd.join(" ")}\` manually.`));
1762
1809
  }
1763
1810
  }
1811
+ if (gitInitialized) await commitScaffold(options.targetDirectory);
1764
1812
  await linkScaffoldToCloud(options);
1765
1813
  console.log("");
1766
1814
  console.log(`${chalk.green.bold("✓")} Project ${chalk.bold(options.projectName)} created successfully!`);
@@ -2005,18 +2053,51 @@ project directory ${path.basename(options.targetDirectory)}/ was created and is
2005
2053
  fs.writeFileSync(fullPath, content, "utf-8");
2006
2054
  }
2007
2055
  }
2008
- async function isPortAvailable(port) {
2056
+ /** `undefined` binds the wildcard address, which is a different question — see isPortAvailable. */
2057
+ function canBind(port, host) {
2009
2058
  return new Promise((resolve) => {
2010
2059
  const server = net.createServer();
2011
- server.once("error", () => {
2012
- resolve(false);
2060
+ server.once("error", (err) => {
2061
+ resolve(err.code === "EAFNOSUPPORT" || err.code === "EADDRNOTAVAIL");
2013
2062
  });
2014
2063
  server.once("listening", () => {
2015
2064
  server.close(() => resolve(true));
2016
2065
  });
2017
- server.listen(port);
2066
+ if (host === void 0) server.listen(port);
2067
+ else server.listen(port, host);
2018
2068
  });
2019
2069
  }
2070
+ /**
2071
+ * Whether `port` is free — on the wildcard address *and* on both loopback addresses.
2072
+ *
2073
+ * All three, because on macOS/BSD a successful bind does not mean the port is
2074
+ * unused. Sockets carry `SO_REUSEADDR` (Node sets it), under which a wildcard
2075
+ * bind and a specific-address bind on the same port do not conflict — in either
2076
+ * direction. So each probe alone has a blind spot, and they are different ones:
2077
+ *
2078
+ * - **Wildcard only** (what this used to do) misses a server bound to
2079
+ * `127.0.0.1` and `[::1]` — a Homebrew or Postgres.app install, i.e. most
2080
+ * developer machines. 5432 was reported free while it was already serving
2081
+ * another project's database. Docker then published `*:5432` for the same
2082
+ * reason and the container started cleanly, with no "port already allocated"
2083
+ * error anywhere to hint at the collision. `DATABASE_URL` pointed at
2084
+ * `localhost:5432`, `localhost` resolves to `::1` first, and every command
2085
+ * reported success while reading and writing the *pre-existing* database — a
2086
+ * `db push` would have created tables, roles and RLS policies inside it.
2087
+ *
2088
+ * - **Loopback only** misses the opposite case: Docker Desktop publishes a
2089
+ * container's port on `*`, and a specific-address bind succeeds right past it.
2090
+ * That port is free to probe and unusable to publish, so `docker compose up -d
2091
+ * db` fails on "Bind for 0.0.0.0:PORT failed: port is already allocated" —
2092
+ * loudly, but only after the project has been generated around the bad port.
2093
+ *
2094
+ * Requiring all three costs three sockets and leaves neither gap. The wildcard
2095
+ * bind is the one the container itself has to make; the loopback binds are the
2096
+ * addresses `DATABASE_URL` will actually name.
2097
+ */
2098
+ async function isPortAvailable(port) {
2099
+ return await canBind(port) && await canBind(port, "127.0.0.1") && await canBind(port, "::1");
2100
+ }
2020
2101
  async function findAvailablePort(startPort) {
2021
2102
  let port = startPort;
2022
2103
  while (!await isPortAvailable(port)) port++;
@@ -2086,6 +2167,7 @@ async function configureEnvFile(targetDirectory, databaseUrl) {
2086
2167
  envContent = envContent.replace(/^#\s*REBASE_SERVICE_KEY=.*$/m, `REBASE_SERVICE_KEY=${serviceKey}`);
2087
2168
  const composeApiPort = /^PORT=(\d+)/m.exec(envContent)?.[1] ?? "3001";
2088
2169
  envContent = envContent.replace(/^#\s*CORS_ORIGINS=.*$/m, `CORS_ORIGINS=http://localhost:${composeApiPort}`);
2170
+ envContent = envContent.replace(/^#?\s*VITE_API_URL=.*$/m, "VITE_API_URL=");
2089
2171
  const { tag: runtimeVersion, note } = resolveRuntimeImageTag(readCliVersion());
2090
2172
  const pinned = `${note ? `${note}\n` : ""}REBASE_VERSION=${runtimeVersion}`;
2091
2173
  envContent = /^#?\s*REBASE_VERSION=.*$/m.test(envContent) ? envContent.replace(/^#?\s*REBASE_VERSION=.*$/m, pinned) : `${envContent.trimEnd()}\n\n# The Rebase runtime image tag docker-compose.yml pulls.\n# Change this and restart to upgrade; your project bundle is untouched.\n${pinned}\n`;
@@ -2096,7 +2178,7 @@ async function configureEnvFile(targetDirectory, databaseUrl) {
2096
2178
  envContent = envContent.replace(/^DATABASE_URL=.*$/m, `DATABASE_URL=${pinnedUrl}\nDATABASE_PASSWORD=${dbPassword}`);
2097
2179
  } else {
2098
2180
  const dbPort = await findAvailablePort(5432);
2099
- envContent = envContent.replace(/^DATABASE_URL=.*$/m, `DATABASE_URL=postgresql://rebase_app:${dbPassword}@localhost:${dbPort}/rebase?options=-c%20search_path=public&sslmode=disable\nDATABASE_PASSWORD=${dbPassword}`);
2181
+ envContent = envContent.replace(/^DATABASE_URL=.*$/m, `DATABASE_URL=postgresql://rebase_app:${dbPassword}@127.0.0.1:${dbPort}/rebase?options=-c%20search_path=public&sslmode=disable\nDATABASE_PASSWORD=${dbPassword}`);
2100
2182
  const dockerComposePath = path.join(targetDirectory, "docker-compose.yml");
2101
2183
  if (fs.existsSync(dockerComposePath)) {
2102
2184
  let dockerComposeContent = fs.readFileSync(dockerComposePath, "utf-8");
@@ -4846,6 +4928,61 @@ function assertBuiltForPath(indexHtml, basePath, appName) {
4846
4928
  build config — see docs/apps-and-runtimes.md §4.2.`);
4847
4929
  }
4848
4930
  /**
4931
+ * The environment every static app is built with, wherever that build is driven from.
4932
+ *
4933
+ * Shared because there are two drivers — `foldFrontendIntoBundle` here, and
4934
+ * `buildAssetApp` in `build.ts` for a standalone `type: "static"` app — and they
4935
+ * had already drifted: the path variables were duplicated into both, so a fix
4936
+ * applied to one shipped a bundle built the old way from the other. One function
4937
+ * makes that impossible rather than merely unlikely.
4938
+ *
4939
+ * ## REBASE_APP_*
4940
+ *
4941
+ * The declared path is a build-time input, not only a serving concern: Vite
4942
+ * reads `base` from REBASE_APP_BASE, and the trailing slash is that field's
4943
+ * convention. See `assertBuiltForPath`.
4944
+ *
4945
+ * ## NODE_ENV
4946
+ *
4947
+ * A built app is a production artifact by construction, so build it as one. Not
4948
+ * a formality: the scaffold's `.env` carries `NODE_ENV=development` for the dev
4949
+ * backend, and Vite's `loadEnv` promotes a `NODE_ENV` found in an env file into
4950
+ * the build unless the environment already sets one. So `rebase build` and
4951
+ * `rebase cloud deploy` shipped a *development* bundle — `import.meta.env.DEV
4952
+ * === true`, development React, dev-only branches live — from commands whose
4953
+ * whole purpose is to produce something deployable. Setting it here is what
4954
+ * closes it: Vite consults the env file's NODE_ENV only when `process.env`
4955
+ * has none.
4956
+ *
4957
+ * ## VITE_API_URL
4958
+ *
4959
+ * An app served by the backend it talks to has its API on its own origin by
4960
+ * construction, so a baked-in absolute URL can only be wrong. It was: that same
4961
+ * `.env` carries `VITE_API_URL=http://localhost:3001` and
4962
+ * `frontend/vite.config.ts` reads the project root via `envDir: ".."`, so a
4963
+ * stock deploy shipped a site whose every request went to whoever ran the build
4964
+ * — passing every server-side health check on the way out. Blanking it here
4965
+ * fixes the bundle even for a project whose `.env` predates the `init` fix, or
4966
+ * was written by hand. Empty is the right value rather than a missing one: the
4967
+ * client falls back to `window.location.origin`, which keeps working when a
4968
+ * custom domain is added.
4969
+ *
4970
+ * Vite prioritises `process.env.VITE_*` over `.env` files, so an explicit
4971
+ * `VITE_API_URL=https://api.example.com rebase cloud deploy` still wins — the
4972
+ * cross-origin escape hatch stays open, it just has to be deliberate. Nothing on
4973
+ * this path loads the project `.env` into `process.env`, so a value inherited
4974
+ * here really was set by the caller.
4975
+ */
4976
+ function staticBuildEnv(appPath, appName) {
4977
+ return {
4978
+ REBASE_APP_PATH: appPath,
4979
+ REBASE_APP_BASE: appPath === "/" ? "/" : `${appPath}/`,
4980
+ REBASE_APP_NAME: appName,
4981
+ NODE_ENV: "production",
4982
+ VITE_API_URL: process.env.VITE_API_URL ?? ""
4983
+ };
4984
+ }
4985
+ /**
4849
4986
  * Build the project's static apps and fold them into the backend bundle.
4850
4987
  *
4851
4988
  * Throws rather than exiting, so the caller decides whether a missing frontend
@@ -4864,11 +5001,7 @@ async function foldFrontendIntoBundle(options) {
4864
5001
  cwd: projectRoot,
4865
5002
  stdio: "inherit",
4866
5003
  shell: true,
4867
- env: {
4868
- REBASE_APP_PATH: app.path,
4869
- REBASE_APP_BASE: app.path === "/" ? "/" : `${app.path}/`,
4870
- REBASE_APP_NAME: app.name
4871
- }
5004
+ env: staticBuildEnv(app.path, app.name)
4872
5005
  });
4873
5006
  const assetsDir = path.join(projectRoot, app.output);
4874
5007
  if (!fs.existsSync(assetsDir)) throw new Error(`"${app.name}" declared output "${app.output}" does not exist after building — the bundle would ship without a frontend.`);
@@ -5058,11 +5191,7 @@ async function buildAssetApp(projectRoot, name, app, runtimeRange, outOverride)
5058
5191
  cwd: projectRoot,
5059
5192
  stdio: "inherit",
5060
5193
  shell: true,
5061
- env: {
5062
- REBASE_APP_PATH: basePath,
5063
- REBASE_APP_BASE: basePath === "/" ? "/" : `${basePath}/`,
5064
- REBASE_APP_NAME: name
5065
- }
5194
+ env: staticBuildEnv(basePath, name)
5066
5195
  });
5067
5196
  } catch {
5068
5197
  console.error(chalk.red(` ✗ build command failed for "${name}"`));
@@ -11184,6 +11313,6 @@ function telemetryNotice() {
11184
11313
  return chalk.gray(`Usage sharing: ${sharing ? "on" : "off"} — ${chalk.cyan("rebase telemetry")} to inspect or change\n`);
11185
11314
  }
11186
11315
  //#endregion
11187
- export { CURRENT_RUNTIME_RANGE, DEFAULT_BUNDLE_DIR, DEFAULT_CONFIG_DIR, DEFAULT_CRONS_DIR, DEFAULT_FUNCTIONS_DIR, DEFAULT_SCHEMA_FILE, DEV_PORT_FILENAME, MANIFEST_FILENAME, ManifestError, TEMPLATE_PLACEHOLDER_FILES, appsCommand, assessManagedCompatibility, authCommand, buildBundle, buildCommand, buildInitQuestions, buildStaticBundle, buildableApps, cloudCommand, collectDeclaredDependencies, configureEnvFile, createRebaseApp, dbCommand, detectFrameworkDepDrift, detectNativeDependencies, detectPackageManager, detectStorageAuthorize, devCommand, doctorCommand, ejectCommand, entry, findBackendApp, findBackendDir, findEnvFile, findFrontendDir, findProjectRoot, findUnusedServerEntry, foldStaticIntoBundle, formatCdTarget, generateSdkCommand, getActiveBackendPlugin, getPMCommands, getProjectPort, isIdentifierLike, isPnpmAvailable, loadManifest, manifestExists, manifestPath, normalizeEsmSpecifiers, pnpmAvailabilityFromProbe, positionals, printInitHelp, readEnvFile, requireBackendDir, requireProjectRoot, resetPnpmAvailabilityCache, resolveBackendPaths, resolveCliVersion, resolveExampleBaseUrl, resolveLocalBin, resolvePluginCliScript, resolveRuntimeImageTag, resolveStartPort, resolveTsx, schemaCommand, selectUserForEmail, startCommand, synthesizeManifest, validateManifest, validateProjectName, validateTsxInstallation, writeManifest };
11316
+ export { CURRENT_RUNTIME_RANGE, DEFAULT_BUNDLE_DIR, DEFAULT_CONFIG_DIR, DEFAULT_CRONS_DIR, DEFAULT_FUNCTIONS_DIR, DEFAULT_SCHEMA_FILE, DEV_PORT_FILENAME, MANIFEST_FILENAME, ManifestError, TEMPLATE_PLACEHOLDER_FILES, appsCommand, assessManagedCompatibility, authCommand, buildBundle, buildCommand, buildInitQuestions, buildStaticBundle, buildableApps, cloudCommand, collectDeclaredDependencies, configureEnvFile, createRebaseApp, dbCommand, detectFrameworkDepDrift, detectNativeDependencies, detectPackageManager, detectStorageAuthorize, devCommand, doctorCommand, ejectCommand, entry, findBackendApp, findBackendDir, findEnvFile, findFrontendDir, findProjectRoot, findUnusedServerEntry, foldStaticIntoBundle, formatCdTarget, generateSdkCommand, getActiveBackendPlugin, getPMCommands, getProjectPort, isIdentifierLike, isPnpmAvailable, isPortAvailable, loadManifest, manifestExists, manifestPath, normalizeEsmSpecifiers, pnpmAvailabilityFromProbe, positionals, printInitHelp, readEnvFile, requireBackendDir, requireProjectRoot, resetPnpmAvailabilityCache, resolveBackendPaths, resolveCliVersion, resolveExampleBaseUrl, resolveLocalBin, resolvePluginCliScript, resolveRuntimeImageTag, resolveStartPort, resolveTsx, schemaCommand, selectUserForEmail, startCommand, synthesizeManifest, validateManifest, validateProjectName, validateTsxInstallation, writeManifest };
11188
11317
 
11189
11318
  //# sourceMappingURL=index.es.js.map