@rebasepro/cli 0.12.1-canary.gf4240e3 → 0.13.0
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/dist/commands/cloud/context.d.ts +25 -0
- package/dist/commands/cloud/projects.d.ts +32 -1
- package/dist/index.es.js +177 -37
- package/dist/index.es.js.map +1 -1
- package/dist/telemetry/identity.d.ts +11 -3
- package/dist/telemetry/index.d.ts +10 -2
- package/dist/telemetry/payload.d.ts +0 -8
- package/package.json +7 -7
|
@@ -24,7 +24,32 @@ export declare function requireClient(rawArgs: string[]): Promise<{
|
|
|
24
24
|
client: CloudClient;
|
|
25
25
|
url: string;
|
|
26
26
|
}>;
|
|
27
|
+
/** One place a deploy can actually land, as the control plane describes it. */
|
|
28
|
+
export interface DeployTarget {
|
|
29
|
+
clusterId?: string | null;
|
|
30
|
+
provider: string;
|
|
31
|
+
region?: string;
|
|
32
|
+
label?: string;
|
|
33
|
+
baseDomain?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface PlatformConfig {
|
|
36
|
+
tenantBaseDomain?: string;
|
|
37
|
+
deployTargets?: DeployTarget[];
|
|
38
|
+
}
|
|
39
|
+
export declare function fetchPlatformConfig(client: CloudClient, url: string): Promise<PlatformConfig | undefined>;
|
|
40
|
+
/**
|
|
41
|
+
* The base domain tenant projects are served at, derived from the same
|
|
42
|
+
* TENANT_BASE_DOMAIN the ingress and the console read (see
|
|
43
|
+
* saas/backend/src/utils/tenant-domain.ts).
|
|
44
|
+
*/
|
|
27
45
|
export declare function fetchTenantBaseDomain(client: CloudClient, url: string): Promise<string | undefined>;
|
|
46
|
+
/**
|
|
47
|
+
* The infrastructure a deploy for this control plane would ACTUALLY use, in the
|
|
48
|
+
* resolver's own preference order (saas/backend/src/k8s/resolve.ts).
|
|
49
|
+
*
|
|
50
|
+
* @returns the targets, or `undefined` when the control plane cannot say.
|
|
51
|
+
*/
|
|
52
|
+
export declare function fetchDeployTargets(client: CloudClient, url: string): Promise<DeployTarget[] | undefined>;
|
|
28
53
|
/**
|
|
29
54
|
* Public host for a project — `<subdomain>.<base>`, or the bare subdomain when
|
|
30
55
|
* the base domain is unknown.
|
|
@@ -1,5 +1,36 @@
|
|
|
1
|
-
import { type CloudClient } from "./context";
|
|
1
|
+
import { type DeployTarget, type CloudClient } from "./context";
|
|
2
2
|
export declare function listProjects(rawArgs: string[]): Promise<void>;
|
|
3
|
+
/**
|
|
4
|
+
* Where this project says it runs.
|
|
5
|
+
*
|
|
6
|
+
* `provider`/`region` are a *request*: no code downstream reads them to pick a
|
|
7
|
+
* deploy target — that comes from the project's cluster record or the ambient
|
|
8
|
+
* in-cluster context (saas/backend/src/k8s/resolve.ts). So a wrong value here is
|
|
9
|
+
* never contradicted by a failure; it just sits in the record. The CLI used to
|
|
10
|
+
* default to `hetzner`/`nbg1` unconditionally, which is how projects running on
|
|
11
|
+
* our GKE cluster came to describe themselves as Hetzner in the console — and
|
|
12
|
+
* `provider` is half the Stripe compute lookup key (`compute_<provider>_<vmSize>`),
|
|
13
|
+
* so that is a mispricing, not a cosmetic slip.
|
|
14
|
+
*
|
|
15
|
+
* The control plane already publishes the infrastructure that actually exists,
|
|
16
|
+
* and the console's create wizard reads it. Ask the same question here.
|
|
17
|
+
*
|
|
18
|
+
* Exported for tests: the decision is pure, so it can be pinned without a
|
|
19
|
+
* control plane. The fetching and the exit live in `resolveRequestedTarget`.
|
|
20
|
+
*
|
|
21
|
+
* @param requested `--provider`, if the caller named one. An explicit flag wins:
|
|
22
|
+
* it is the caller stating intent, and `deploy` corrects the record anyway.
|
|
23
|
+
* @param targets What the control plane says exists, or `undefined` when it
|
|
24
|
+
* cannot say — an older deployment with no `platform-config`, or a failed
|
|
25
|
+
* request. That is different from an empty list, which is a control plane
|
|
26
|
+
* stating it has no infrastructure at all.
|
|
27
|
+
* @returns the target to record, or `null` when the control plane answered that
|
|
28
|
+
* there is none.
|
|
29
|
+
*/
|
|
30
|
+
export declare function chooseRequestedTarget(requested: string | undefined, targets: DeployTarget[] | undefined): {
|
|
31
|
+
provider: string;
|
|
32
|
+
region?: string;
|
|
33
|
+
} | null;
|
|
3
34
|
export declare function createProject(rawArgs: string[]): Promise<void>;
|
|
4
35
|
export declare function projectInfo(rawArgs: string[], projectRef: string): Promise<void>;
|
|
5
36
|
export declare function deleteProject(rawArgs: string[], projectRef: string): Promise<void>;
|
package/dist/index.es.js
CHANGED
|
@@ -528,33 +528,51 @@ async function requireClient(rawArgs) {
|
|
|
528
528
|
};
|
|
529
529
|
}
|
|
530
530
|
/**
|
|
531
|
-
* The
|
|
532
|
-
* plane (`platform-config`, which derives it from the same TENANT_BASE_DOMAIN
|
|
533
|
-
* the ingress and the console read — see saas/backend/src/utils/tenant-domain.ts).
|
|
531
|
+
* The control plane's public, non-secret self-description (`platform-config`).
|
|
534
532
|
*
|
|
535
|
-
*
|
|
536
|
-
* serves tenants at `rebase.website
|
|
537
|
-
*
|
|
538
|
-
*
|
|
533
|
+
* None of it is knowable from the CLI side: it is per-deployment configuration —
|
|
534
|
+
* production serves tenants at `rebase.website` on GKE, a dev control plane at
|
|
535
|
+
* `localhost` on Docker. Guessing produced two separate lies: a congratulation
|
|
536
|
+
* URL that resolved nowhere near the app, and a `provider` the project does not
|
|
537
|
+
* run on (see `createProject`).
|
|
539
538
|
*
|
|
540
539
|
* Cached per host for the process: it is fixed for a control plane's lifetime,
|
|
541
540
|
* and `projects list` formats one host per row off a single fetch.
|
|
542
541
|
*
|
|
543
|
-
* @returns the
|
|
542
|
+
* @returns the config, or `undefined` if the control plane doesn't serve
|
|
544
543
|
* `platform-config` (an older deployment) or the request failed. A failure is
|
|
545
|
-
* cached too —
|
|
546
|
-
*
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
544
|
+
* cached too — a short-lived CLI should not retry once per row. Note the
|
|
545
|
+
* distinction callers rely on: `undefined` means "this control plane cannot
|
|
546
|
+
* tell us", whereas `deployTargets: []` is a control plane stating that it has
|
|
547
|
+
* no infrastructure configured.
|
|
548
|
+
*/
|
|
549
|
+
var platformConfigCache = /* @__PURE__ */ new Map();
|
|
550
|
+
function fetchPlatformConfig(client, url) {
|
|
551
|
+
let pending = platformConfigCache.get(url);
|
|
551
552
|
if (!pending) {
|
|
552
|
-
pending = client.functions.invoke("platform-config", void 0, { method: "GET" }).then((cfg) => cfg
|
|
553
|
-
|
|
553
|
+
pending = client.functions.invoke("platform-config", void 0, { method: "GET" }).then((cfg) => cfg ?? void 0).catch(() => void 0);
|
|
554
|
+
platformConfigCache.set(url, pending);
|
|
554
555
|
}
|
|
555
556
|
return pending;
|
|
556
557
|
}
|
|
557
558
|
/**
|
|
559
|
+
* The base domain tenant projects are served at, derived from the same
|
|
560
|
+
* TENANT_BASE_DOMAIN the ingress and the console read (see
|
|
561
|
+
* saas/backend/src/utils/tenant-domain.ts).
|
|
562
|
+
*/
|
|
563
|
+
function fetchTenantBaseDomain(client, url) {
|
|
564
|
+
return fetchPlatformConfig(client, url).then((cfg) => cfg?.tenantBaseDomain?.trim() || void 0);
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* The infrastructure a deploy for this control plane would ACTUALLY use, in the
|
|
568
|
+
* resolver's own preference order (saas/backend/src/k8s/resolve.ts).
|
|
569
|
+
*
|
|
570
|
+
* @returns the targets, or `undefined` when the control plane cannot say.
|
|
571
|
+
*/
|
|
572
|
+
function fetchDeployTargets(client, url) {
|
|
573
|
+
return fetchPlatformConfig(client, url).then((cfg) => Array.isArray(cfg?.deployTargets) ? cfg.deployTargets : void 0);
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
558
576
|
* Public host for a project — `<subdomain>.<base>`, or the bare subdomain when
|
|
559
577
|
* the base domain is unknown.
|
|
560
578
|
*
|
|
@@ -904,10 +922,26 @@ function durationBucket(ms) {
|
|
|
904
922
|
* turning into an incident. Strings are capped at 64 characters because no
|
|
905
923
|
* legitimate enumerated value is longer, and a path or a message always is.
|
|
906
924
|
*/
|
|
925
|
+
/**
|
|
926
|
+
* Key names that shadow an `Object.prototype` member.
|
|
927
|
+
*
|
|
928
|
+
* `__proto__` is already excluded by the pattern (it starts with an
|
|
929
|
+
* underscore), and assigning any of these to an object literal shadows rather
|
|
930
|
+
* than pollutes — so nothing is exploitable here. They are refused because a
|
|
931
|
+
* stored property called `constructor` is a trap for every consumer downstream
|
|
932
|
+
* that reaches for `properties.constructor` and gets a string.
|
|
933
|
+
*/
|
|
934
|
+
var RESERVED_KEYS = /* @__PURE__ */ new Set([
|
|
935
|
+
"constructor",
|
|
936
|
+
"prototype",
|
|
937
|
+
"hasownproperty",
|
|
938
|
+
"tostring",
|
|
939
|
+
"valueof"
|
|
940
|
+
]);
|
|
907
941
|
function sanitize(properties) {
|
|
908
942
|
const out = {};
|
|
909
943
|
for (const [key, value] of Object.entries(properties)) {
|
|
910
|
-
if (!/^[a-z][a-z0-9_]{0,31}$/.test(key)) continue;
|
|
944
|
+
if (!/^[a-z][a-z0-9_]{0,31}$/.test(key) || RESERVED_KEYS.has(key.toLowerCase())) continue;
|
|
911
945
|
if (typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) out[key] = value;
|
|
912
946
|
else if (typeof value === "string" && value.length > 0 && value.length <= 64) {
|
|
913
947
|
if (!/[/\\@:\s]/.test(value)) out[key] = value;
|
|
@@ -982,16 +1016,29 @@ function ensureMachineId() {
|
|
|
982
1016
|
/**
|
|
983
1017
|
* The checkout's id, generating one if this project has none.
|
|
984
1018
|
*
|
|
985
|
-
*
|
|
986
|
-
*
|
|
987
|
-
*
|
|
1019
|
+
* The directory is created when it is missing, but **only** where a
|
|
1020
|
+
* `rebase.json` proves this really is a project root. An earlier version
|
|
1021
|
+
* required `.rebase/` to already exist, on the assumption that `rebase init`
|
|
1022
|
+
* created it — it does not. It is written only when a scaffold is linked to
|
|
1023
|
+
* Rebase Cloud, so every self-hosted project reported no `projectId` at all,
|
|
1024
|
+
* for ever. That silently broke the funnel this id exists for, on exactly the
|
|
1025
|
+
* population the telemetry is meant to learn about.
|
|
1026
|
+
*
|
|
1027
|
+
* The `rebase.json` check is what keeps the fix from being "scatter `.rebase/`
|
|
1028
|
+
* wherever a command happens to run": no manifest, no project, no directory,
|
|
1029
|
+
* and the event simply reports no project.
|
|
988
1030
|
*/
|
|
989
1031
|
function ensureProjectId(projectRoot) {
|
|
1032
|
+
if (!fs.existsSync(path.join(projectRoot, "rebase.json"))) return void 0;
|
|
990
1033
|
const dir = path.join(projectRoot, ".rebase");
|
|
991
|
-
|
|
1034
|
+
try {
|
|
1035
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
1036
|
+
} catch {
|
|
1037
|
+
return;
|
|
1038
|
+
}
|
|
992
1039
|
const file = path.join(dir, "state.json");
|
|
993
1040
|
let state = {};
|
|
994
|
-
try {
|
|
1041
|
+
if (fs.existsSync(file)) try {
|
|
995
1042
|
const raw = JSON.parse(fs.readFileSync(file, "utf-8"));
|
|
996
1043
|
if (raw && typeof raw === "object") state = raw;
|
|
997
1044
|
} catch {
|
|
@@ -1060,16 +1107,29 @@ function suppressionReason(env = process.env, cwd = process.cwd()) {
|
|
|
1060
1107
|
function isEnabled(env = process.env, cwd = process.cwd()) {
|
|
1061
1108
|
return suppressionReason(env, cwd) === null;
|
|
1062
1109
|
}
|
|
1063
|
-
/**
|
|
1110
|
+
/**
|
|
1111
|
+
* Record the user's answer. `false` is final — nothing prompts again.
|
|
1112
|
+
*
|
|
1113
|
+
* Returns whether the choice could actually be persisted. A read-only or full
|
|
1114
|
+
* home directory makes `writeConfig` throw, and the direction of that failure
|
|
1115
|
+
* matters enormously: someone turning sharing **off** who sees a stack trace,
|
|
1116
|
+
* or worse sees nothing, is left sharing. The caller is expected to say so and
|
|
1117
|
+
* point at `REBASE_TELEMETRY_DISABLED`, which needs no disk.
|
|
1118
|
+
*/
|
|
1064
1119
|
function setConsent(enabled) {
|
|
1065
1120
|
const config = readConfig();
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1121
|
+
try {
|
|
1122
|
+
writeConfig({
|
|
1123
|
+
...config,
|
|
1124
|
+
enabled,
|
|
1125
|
+
decidedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1126
|
+
machineId: enabled ? config.machineId ?? void 0 : void 0
|
|
1127
|
+
});
|
|
1128
|
+
if (enabled) ensureMachineId();
|
|
1129
|
+
return true;
|
|
1130
|
+
} catch {
|
|
1131
|
+
return false;
|
|
1132
|
+
}
|
|
1073
1133
|
}
|
|
1074
1134
|
/**
|
|
1075
1135
|
* Build the event that *would* be sent, without sending it.
|
|
@@ -1899,7 +1959,11 @@ async function replacePlaceholders(options) {
|
|
|
1899
1959
|
const prereleasePins = [...unreleased].filter(([, version]) => version === "latest" || version.includes("-"));
|
|
1900
1960
|
if (cliIsStable && prereleasePins.length > 0) {
|
|
1901
1961
|
const lines = prereleasePins.map(([name, version]) => ` ${name} → ${version}`).join("\n");
|
|
1902
|
-
throw new Error(`Rebase ${cliVersion} is not fully published to npm.\n\nThese packages have no ${cliVersion} release, so the newest thing on the\nregistry is a prerelease:\n\n${lines}\n\nScaffolding would pin those alongside the ${cliVersion} packages and produce\nan app that cannot install or run. That is a release gap in Rebase itself
|
|
1962
|
+
throw new Error(`Rebase ${cliVersion} is not fully published to npm.\n\nThese packages have no ${cliVersion} release, so the newest thing on the\nregistry is a prerelease:\n\n${lines}\n\nScaffolding would pin those alongside the ${cliVersion} packages and produce\nan app that cannot install or run. That is a release gap in Rebase itself —
|
|
1963
|
+
not a problem with your machine, your network, or your package manager.
|
|
1964
|
+
|
|
1965
|
+
Stopped before writing dependency versions or installing anything. The
|
|
1966
|
+
project directory ${path.basename(options.targetDirectory)}/ was created and is safe to delete.\nPlease report this with the list above.`);
|
|
1903
1967
|
}
|
|
1904
1968
|
for (const [fullPath, originalContent] of fileContents.entries()) {
|
|
1905
1969
|
let content = originalContent.replace(/\{\{PROJECT_NAME\}\}/g, options.projectName);
|
|
@@ -2303,6 +2367,7 @@ async function schemaCommand(subcommand, rawArgs) {
|
|
|
2303
2367
|
return;
|
|
2304
2368
|
}
|
|
2305
2369
|
const projectRoot = requireProjectRoot();
|
|
2370
|
+
recordEvent("cli.schema_generate", { subcommand: subcommand ?? "none" }, { projectRoot });
|
|
2306
2371
|
const backendDir = requireBackendDir(projectRoot);
|
|
2307
2372
|
const activePlugin = getActiveBackendPlugin(backendDir);
|
|
2308
2373
|
if (!activePlugin) {
|
|
@@ -2371,6 +2436,7 @@ async function dbCommand(subcommand, rawArgs) {
|
|
|
2371
2436
|
return;
|
|
2372
2437
|
}
|
|
2373
2438
|
const projectRoot = requireProjectRoot();
|
|
2439
|
+
recordEvent("cli.db_push", { subcommand: subcommand ?? "none" }, { projectRoot });
|
|
2374
2440
|
const backendDir = requireBackendDir(projectRoot);
|
|
2375
2441
|
const activePlugin = getActiveBackendPlugin(backendDir);
|
|
2376
2442
|
if (!activePlugin) {
|
|
@@ -4216,7 +4282,7 @@ async function buildBundle(options) {
|
|
|
4216
4282
|
console.log(chalk.yellow(` ⚠ ${unusedEntry} is not the bundle's entry point — it is not compiled or shipped.`));
|
|
4217
4283
|
console.log(chalk.dim(` The runtime boots the bundle itself and mounts ${compiled}.`));
|
|
4218
4284
|
console.log(chalk.dim(` Routes defined there will not exist once deployed: move them to ${paths.functions}/,`));
|
|
4219
|
-
console.log(chalk.dim(
|
|
4285
|
+
console.log(chalk.dim(" or run `rebase eject` to make this file the entrypoint and own the image."));
|
|
4220
4286
|
}
|
|
4221
4287
|
log(options, chalk.dim(` compiling ${includes.length} source group(s) → ${path.relative(projectRoot, outDir)}/`));
|
|
4222
4288
|
cleanOutDir(projectRoot, outDir);
|
|
@@ -5998,12 +6064,21 @@ async function telemetryCommand(rawArgs) {
|
|
|
5998
6064
|
printPayload();
|
|
5999
6065
|
return;
|
|
6000
6066
|
case "enable":
|
|
6001
|
-
setConsent(true)
|
|
6067
|
+
if (!setConsent(true)) {
|
|
6068
|
+
console.error(chalk.red(`Could not write ${configPath()} — sharing was not enabled.`));
|
|
6069
|
+
process.exitCode = 1;
|
|
6070
|
+
return;
|
|
6071
|
+
}
|
|
6002
6072
|
console.log(chalk.green("Anonymous usage sharing enabled."));
|
|
6003
6073
|
console.log(chalk.gray(`Inspect what gets sent with ${chalk.cyan("rebase telemetry show")}.`));
|
|
6004
6074
|
return;
|
|
6005
6075
|
case "disable":
|
|
6006
|
-
setConsent(false)
|
|
6076
|
+
if (!setConsent(false)) {
|
|
6077
|
+
console.error(chalk.red(`Could not write ${configPath()} — sharing is still ON.`));
|
|
6078
|
+
console.error(chalk.yellow(`Set ${chalk.cyan("REBASE_TELEMETRY_DISABLED=1")} in your environment instead; it needs no file.`));
|
|
6079
|
+
process.exitCode = 1;
|
|
6080
|
+
return;
|
|
6081
|
+
}
|
|
6007
6082
|
console.log(chalk.gray("Anonymous usage sharing disabled. Nothing further will be sent."));
|
|
6008
6083
|
return;
|
|
6009
6084
|
default:
|
|
@@ -6363,6 +6438,54 @@ function providerDefaults(provider) {
|
|
|
6363
6438
|
};
|
|
6364
6439
|
}
|
|
6365
6440
|
}
|
|
6441
|
+
/**
|
|
6442
|
+
* Where this project says it runs.
|
|
6443
|
+
*
|
|
6444
|
+
* `provider`/`region` are a *request*: no code downstream reads them to pick a
|
|
6445
|
+
* deploy target — that comes from the project's cluster record or the ambient
|
|
6446
|
+
* in-cluster context (saas/backend/src/k8s/resolve.ts). So a wrong value here is
|
|
6447
|
+
* never contradicted by a failure; it just sits in the record. The CLI used to
|
|
6448
|
+
* default to `hetzner`/`nbg1` unconditionally, which is how projects running on
|
|
6449
|
+
* our GKE cluster came to describe themselves as Hetzner in the console — and
|
|
6450
|
+
* `provider` is half the Stripe compute lookup key (`compute_<provider>_<vmSize>`),
|
|
6451
|
+
* so that is a mispricing, not a cosmetic slip.
|
|
6452
|
+
*
|
|
6453
|
+
* The control plane already publishes the infrastructure that actually exists,
|
|
6454
|
+
* and the console's create wizard reads it. Ask the same question here.
|
|
6455
|
+
*
|
|
6456
|
+
* Exported for tests: the decision is pure, so it can be pinned without a
|
|
6457
|
+
* control plane. The fetching and the exit live in `resolveRequestedTarget`.
|
|
6458
|
+
*
|
|
6459
|
+
* @param requested `--provider`, if the caller named one. An explicit flag wins:
|
|
6460
|
+
* it is the caller stating intent, and `deploy` corrects the record anyway.
|
|
6461
|
+
* @param targets What the control plane says exists, or `undefined` when it
|
|
6462
|
+
* cannot say — an older deployment with no `platform-config`, or a failed
|
|
6463
|
+
* request. That is different from an empty list, which is a control plane
|
|
6464
|
+
* stating it has no infrastructure at all.
|
|
6465
|
+
* @returns the target to record, or `null` when the control plane answered that
|
|
6466
|
+
* there is none.
|
|
6467
|
+
*/
|
|
6468
|
+
function chooseRequestedTarget(requested, targets) {
|
|
6469
|
+
if (requested) return {
|
|
6470
|
+
provider: requested,
|
|
6471
|
+
region: void 0
|
|
6472
|
+
};
|
|
6473
|
+
if (!targets) return {
|
|
6474
|
+
provider: "hetzner",
|
|
6475
|
+
region: void 0
|
|
6476
|
+
};
|
|
6477
|
+
if (targets.length === 0) return null;
|
|
6478
|
+
const [target] = targets;
|
|
6479
|
+
return {
|
|
6480
|
+
provider: target.provider,
|
|
6481
|
+
region: target.region?.trim() || void 0
|
|
6482
|
+
};
|
|
6483
|
+
}
|
|
6484
|
+
async function resolveRequestedTarget(client, url, requested) {
|
|
6485
|
+
const chosen = chooseRequestedTarget(requested, await fetchDeployTargets(client, url));
|
|
6486
|
+
if (!chosen) fail("This control plane has no deploy targets configured.", `Register a cluster, or pass ${chalk.bold("--provider")} and ${chalk.bold("--region")} to record one anyway.`);
|
|
6487
|
+
return chosen;
|
|
6488
|
+
}
|
|
6366
6489
|
async function createProject(rawArgs) {
|
|
6367
6490
|
const args = arg({
|
|
6368
6491
|
"--name": String,
|
|
@@ -6398,9 +6521,10 @@ async function createProject(rawArgs) {
|
|
|
6398
6521
|
const subdomain = (args["--subdomain"] || a.subdomain || "").trim().toLowerCase();
|
|
6399
6522
|
const gitRepoUrl = (args["--repo"] || a.repo || "").trim();
|
|
6400
6523
|
const gitBranch = (args["--branch"] || a.branch || "main").trim();
|
|
6401
|
-
const
|
|
6524
|
+
const target = await resolveRequestedTarget(client, url, (args["--provider"] || a.provider)?.trim() || void 0);
|
|
6525
|
+
const provider = target.provider;
|
|
6402
6526
|
const defaults = providerDefaults(provider);
|
|
6403
|
-
const region = (args["--region"] || defaults.region).trim();
|
|
6527
|
+
const region = (args["--region"] || target.region || defaults.region).trim();
|
|
6404
6528
|
const vmSize = (args["--vm-size"] || defaults.vmSize).trim();
|
|
6405
6529
|
if (!name || !subdomain) fail("Name and subdomain are required.");
|
|
6406
6530
|
try {
|
|
@@ -10750,7 +10874,23 @@ ${chalk.green.bold("Options")}
|
|
|
10750
10874
|
${chalk.blue("--help, -h")} Show this help message
|
|
10751
10875
|
|
|
10752
10876
|
${chalk.gray("Documentation: https://rebase.pro/docs")}
|
|
10753
|
-
`);
|
|
10877
|
+
${telemetryNotice()}`);
|
|
10878
|
+
}
|
|
10879
|
+
/**
|
|
10880
|
+
* One line about usage sharing, in the global help.
|
|
10881
|
+
*
|
|
10882
|
+
* Every other tool that collects anything prints a first-run notice. Ours asks
|
|
10883
|
+
* at the end of `rebase init` — but someone who installs the CLI and never runs
|
|
10884
|
+
* `init`, or who joins a project someone else scaffolded, would otherwise never
|
|
10885
|
+
* learn the subsystem exists. This is the cheapest place to close that: the
|
|
10886
|
+
* help is what an unfamiliar user reads first.
|
|
10887
|
+
*
|
|
10888
|
+
* It states the current setting rather than a generic sentence, so it is also
|
|
10889
|
+
* the fastest answer to "is this thing on?".
|
|
10890
|
+
*/
|
|
10891
|
+
function telemetryNotice() {
|
|
10892
|
+
const sharing = isEnabled();
|
|
10893
|
+
return chalk.gray(`Usage sharing: ${sharing ? "on" : "off"} — ${chalk.cyan("rebase telemetry")} to inspect or change\n`);
|
|
10754
10894
|
}
|
|
10755
10895
|
//#endregion
|
|
10756
10896
|
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, requireBackendDir, requireProjectRoot, resetPnpmAvailabilityCache, resolveBackendPaths, resolveCliVersion, resolveExampleBaseUrl, resolveLocalBin, resolvePluginCliScript, resolveStartPort, resolveTsx, schemaCommand, startCommand, synthesizeManifest, validateManifest, validateProjectName, validateTsxInstallation, writeManifest };
|