@rebasepro/cli 0.19.2-canary.g98b88fd → 0.19.2-canary.gef769df
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/index.es.js +34 -75
- package/dist/index.es.js.map +1 -1
- package/dist/telemetry/consent.d.ts +3 -25
- package/package.json +7 -7
- package/templates/overlays/baas/backend/package.json +1 -1
- package/templates/overlays/baas/config/package.json +1 -1
- package/templates/overlays/baas/package.json +1 -1
- package/templates/template/backend/package.json +1 -1
- package/templates/template/config/package.json +1 -1
- package/templates/template/frontend/package.json +4 -4
- package/templates/template/frontend/vite.config.ts +1 -5
- package/templates/template/package.json +1 -1
package/dist/index.es.js
CHANGED
|
@@ -1474,12 +1474,33 @@ async function recordEvent(event, properties = {}, options = {}) {
|
|
|
1474
1474
|
}
|
|
1475
1475
|
//#endregion
|
|
1476
1476
|
//#region src/telemetry/consent.ts
|
|
1477
|
-
/**
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1477
|
+
/**
|
|
1478
|
+
* Asking, and what the question looks like.
|
|
1479
|
+
*
|
|
1480
|
+
* ## Why the prompt comes *after* the work
|
|
1481
|
+
*
|
|
1482
|
+
* The first `rebase init` on a machine is the event most worth having, and it
|
|
1483
|
+
* is the one where no consent exists yet. Asking before scaffolding puts a
|
|
1484
|
+
* privacy negotiation in front of someone who has not yet seen the tool do
|
|
1485
|
+
* anything — the worst possible moment, and a reliable way to get a reflexive
|
|
1486
|
+
* no.
|
|
1487
|
+
*
|
|
1488
|
+
* So the question is asked once the project exists and the user has seen it
|
|
1489
|
+
* work. The event's data is still in memory at that point, so nothing is lost
|
|
1490
|
+
* by waiting, and — this is the part that matters — **nothing has been
|
|
1491
|
+
* transmitted or written**. Declining leaves no id, no file, no record.
|
|
1492
|
+
*
|
|
1493
|
+
* ## Why the payload is shown rather than described
|
|
1494
|
+
*
|
|
1495
|
+
* "Anonymous usage data" is a phrase that has been used to mean almost
|
|
1496
|
+
* anything. Printing the exact JSON costs four lines of output and replaces a
|
|
1497
|
+
* claim the user has to take on faith with something they can read. It is also
|
|
1498
|
+
* the same builder the sender uses, so it cannot drift into a comfortable
|
|
1499
|
+
* fiction.
|
|
1500
|
+
*/
|
|
1501
|
+
/** True when we may ask: no decision recorded, and nothing else forbids it. */
|
|
1502
|
+
function shouldPrompt(env = process.env) {
|
|
1503
|
+
return suppressionReason(env) === "not_asked" && Boolean(process.stdin.isTTY);
|
|
1483
1504
|
}
|
|
1484
1505
|
function renderPreview(event, properties) {
|
|
1485
1506
|
const preview = buildEvent(event, properties, {
|
|
@@ -1495,9 +1516,8 @@ function renderPreview(event, properties) {
|
|
|
1495
1516
|
* CI must behave exactly as it does today, which means not asking and not
|
|
1496
1517
|
* sending.
|
|
1497
1518
|
*/
|
|
1498
|
-
async function promptForConsent(event, properties
|
|
1499
|
-
if (!shouldPrompt(
|
|
1500
|
-
const askedBefore = suppressionReason(process.env) === "declined";
|
|
1519
|
+
async function promptForConsent(event, properties) {
|
|
1520
|
+
if (!shouldPrompt()) return false;
|
|
1501
1521
|
try {
|
|
1502
1522
|
console.log("");
|
|
1503
1523
|
console.log(chalk.bold("Help improve Rebase?"));
|
|
@@ -1511,11 +1531,6 @@ async function promptForConsent(event, properties, options = {}) {
|
|
|
1511
1531
|
console.log("");
|
|
1512
1532
|
console.log(chalk.gray(" No project names, paths, schemas, URLs or error messages. Change your"));
|
|
1513
1533
|
console.log(chalk.gray(` mind any time with ${chalk.cyan("rebase telemetry disable")}.`));
|
|
1514
|
-
if (askedBefore) {
|
|
1515
|
-
console.log("");
|
|
1516
|
-
console.log(chalk.gray(" You declined before, and that is still the answer unless you change it"));
|
|
1517
|
-
console.log(chalk.gray(" here. Asked once per new project; never during ordinary work."));
|
|
1518
|
-
}
|
|
1519
1534
|
console.log("");
|
|
1520
1535
|
const { accepted } = await inquirer.prompt([{
|
|
1521
1536
|
type: "confirm",
|
|
@@ -1524,7 +1539,7 @@ async function promptForConsent(event, properties, options = {}) {
|
|
|
1524
1539
|
default: false
|
|
1525
1540
|
}]);
|
|
1526
1541
|
setConsent(Boolean(accepted));
|
|
1527
|
-
console.log(accepted ? chalk.green(" Thank you — sharing enabled.") : chalk.gray(" Nothing will be sent.
|
|
1542
|
+
console.log(accepted ? chalk.green(" Thank you — sharing enabled.") : chalk.gray(" Nothing will be sent. You will not be asked again."));
|
|
1528
1543
|
console.log("");
|
|
1529
1544
|
return Boolean(accepted);
|
|
1530
1545
|
} catch {
|
|
@@ -1638,7 +1653,7 @@ function buildInitQuestions(params) {
|
|
|
1638
1653
|
type: "input",
|
|
1639
1654
|
name: "projectName",
|
|
1640
1655
|
message: "Project name:",
|
|
1641
|
-
default: "my-app",
|
|
1656
|
+
default: "my-rebase-app",
|
|
1642
1657
|
validate: (input) => validateProjectName(input) ?? true
|
|
1643
1658
|
});
|
|
1644
1659
|
if (headlessArg === void 0) questions.push({
|
|
@@ -1706,7 +1721,7 @@ ${chalk.bold("Usage")}
|
|
|
1706
1721
|
rebase init ${chalk.blue("[name]")} [options]
|
|
1707
1722
|
|
|
1708
1723
|
${chalk.gray("The name may be a nested path (apps/my-app) or \".\" for the current directory.")}
|
|
1709
|
-
${chalk.gray("
|
|
1724
|
+
${chalk.gray("Defaults to \"my-rebase-app\" when omitted with --yes.")}
|
|
1710
1725
|
|
|
1711
1726
|
${chalk.bold("Options")}
|
|
1712
1727
|
${chalk.blue("-t, --template")} ${chalk.gray("<preset>")} blog | ecommerce | blank ${chalk.gray("(default: blog)")}
|
|
@@ -1788,7 +1803,7 @@ async function promptForOptions(rawArgs, pm) {
|
|
|
1788
1803
|
const installFlag = noInstall ? false : args["--install"] ?? false;
|
|
1789
1804
|
const hasInstallFlag = noInstall || args["--install"] === true;
|
|
1790
1805
|
if (isNonInteractive) {
|
|
1791
|
-
const projectName = nameArg || "my-app";
|
|
1806
|
+
const projectName = nameArg || "my-rebase-app";
|
|
1792
1807
|
const targetDirectory = path.resolve(process.cwd(), projectName);
|
|
1793
1808
|
const templateDirectory = path.resolve(cliRoot, "templates", "template");
|
|
1794
1809
|
const pmCommands = getPMCommands(pm);
|
|
@@ -2124,7 +2139,7 @@ async function createProject$1(options) {
|
|
|
2124
2139
|
git: Boolean(options.git),
|
|
2125
2140
|
duration: durationBucket(Date.now() - startedAt)
|
|
2126
2141
|
};
|
|
2127
|
-
if (await promptForConsent("cli.init", initProperties
|
|
2142
|
+
if (await promptForConsent("cli.init", initProperties)) await recordEvent("cli.init", initProperties, { projectRoot: options.targetDirectory });
|
|
2128
2143
|
}
|
|
2129
2144
|
/**
|
|
2130
2145
|
* Apply a template preset by replacing the default collection files.
|
|
@@ -15159,31 +15174,7 @@ function resolveDeployArgs(rawArgs) {
|
|
|
15159
15174
|
appName: positionals[0]
|
|
15160
15175
|
};
|
|
15161
15176
|
}
|
|
15162
|
-
/**
|
|
15163
|
-
* `cli.deploy` — the event that says whether anyone ever ships.
|
|
15164
|
-
*
|
|
15165
|
-
* Declared in `TelemetryEventName` from the start and recorded nowhere, so a
|
|
15166
|
-
* consenting user reported scaffolding, dev servers and schema pushes and never
|
|
15167
|
-
* the one act the product exists for.
|
|
15168
|
-
*
|
|
15169
|
-
* What it carries is deliberately thin. No project id, no app name, no
|
|
15170
|
-
* deployment id, no URL: those are the "project names" and "URLs" the consent
|
|
15171
|
-
* screen promises are never sent, and a deployment id is a durable handle on
|
|
15172
|
-
* somebody's infrastructure. `frameworkVersion` is *our* version, not the
|
|
15173
|
-
* user's data, and it is the one field that makes the rest legible — a failure
|
|
15174
|
-
* rate means nothing without knowing which release it is a rate for.
|
|
15175
|
-
*/
|
|
15176
|
-
async function recordDeploy(o) {
|
|
15177
|
-
await recordEvent("cli.deploy", {
|
|
15178
|
-
followed: o.followed,
|
|
15179
|
-
status: o.status,
|
|
15180
|
-
deduplicated: o.deduplicated,
|
|
15181
|
-
framework_version: o.frameworkVersion ?? null,
|
|
15182
|
-
duration: durationBucket(Date.now() - o.startedAt)
|
|
15183
|
-
}, { projectRoot: process.cwd() });
|
|
15184
|
-
}
|
|
15185
15177
|
async function deployCommand(rawArgs, projectRef) {
|
|
15186
|
-
const startedAt = Date.now();
|
|
15187
15178
|
const { flags: args, appName } = resolveDeployArgs(rawArgs);
|
|
15188
15179
|
if (args["--wait"] && args["--no-follow"]) fail("--wait and --no-follow ask for opposite things.", "`deploy` follows by default — pass neither, or `--no-follow` to return as soon as the build is triggered.", "usage");
|
|
15189
15180
|
const { client, url } = await requireClient(rawArgs);
|
|
@@ -15267,13 +15258,6 @@ async function deployCommand(rawArgs, projectRef) {
|
|
|
15267
15258
|
following: false,
|
|
15268
15259
|
...warningPayload(warnings)
|
|
15269
15260
|
});
|
|
15270
|
-
await recordDeploy({
|
|
15271
|
-
followed: false,
|
|
15272
|
-
status: "not_followed",
|
|
15273
|
-
deduplicated,
|
|
15274
|
-
frameworkVersion,
|
|
15275
|
-
startedAt
|
|
15276
|
-
});
|
|
15277
15261
|
return;
|
|
15278
15262
|
}
|
|
15279
15263
|
if (!isJsonMode()) {
|
|
@@ -15286,13 +15270,6 @@ async function deployCommand(rawArgs, projectRef) {
|
|
|
15286
15270
|
projectId,
|
|
15287
15271
|
url
|
|
15288
15272
|
});
|
|
15289
|
-
await recordDeploy({
|
|
15290
|
-
followed: true,
|
|
15291
|
-
status,
|
|
15292
|
-
deduplicated,
|
|
15293
|
-
frameworkVersion,
|
|
15294
|
-
startedAt
|
|
15295
|
-
});
|
|
15296
15273
|
emit(() => {}, {
|
|
15297
15274
|
deploymentId,
|
|
15298
15275
|
deduplicated,
|
|
@@ -19102,24 +19079,6 @@ async function entry(args) {
|
|
|
19102
19079
|
return;
|
|
19103
19080
|
}
|
|
19104
19081
|
const effectiveSubcommand = parsedArgs["--help"] && !subcommand ? "--help" : subcommand;
|
|
19105
|
-
try {
|
|
19106
|
-
await dispatch(command, effectiveSubcommand, args, parsedArgs, namespacedCommands);
|
|
19107
|
-
} catch (error) {
|
|
19108
|
-
await recordEvent("cli.error", {
|
|
19109
|
-
command: command ?? "none",
|
|
19110
|
-
subcommand: effectiveSubcommand ?? "none",
|
|
19111
|
-
error_type: error instanceof Error ? error.constructor.name : "unknown",
|
|
19112
|
-
usage: Boolean(error && typeof error === "object" && error.isUsageError)
|
|
19113
|
-
}, { projectRoot: process.cwd() });
|
|
19114
|
-
throw error;
|
|
19115
|
-
}
|
|
19116
|
-
}
|
|
19117
|
-
/**
|
|
19118
|
-
* The dispatch, lifted out of {@link entry} so the whole of it sits inside one
|
|
19119
|
-
* `try`. Inlining the switch there would have put the `catch` around the flag
|
|
19120
|
-
* parsing too, which throws its own usage errors before a command is even named.
|
|
19121
|
-
*/
|
|
19122
|
-
async function dispatch(command, effectiveSubcommand, args, parsedArgs, namespacedCommands) {
|
|
19123
19082
|
switch (command) {
|
|
19124
19083
|
case "__dev-db-daemon": {
|
|
19125
19084
|
const { parseDaemonArgs, runDaemon } = await import("./daemon-entry-LTFKtpHy.js");
|