@koda-sl/baker-cli 0.354.0 → 0.355.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/README.md CHANGED
@@ -98,7 +98,12 @@ All commands return a JSON envelope:
98
98
  ### Unknown options are refused
99
99
 
100
100
  An option a command does not declare stops the run with `UNKNOWN_ARGUMENT`, naming the
101
- closest real one. Previously such an option was accepted and ignored, so a call that
101
+ real one it was most likely reaching for, with the first sentence of that option's own
102
+ description. A word the command spells differently is matched by meaning (`--from` and
103
+ `--since` → `--start-date`, `--to` and `--until` → `--end-date`, `--path` and `--url` →
104
+ `--landing`, each only where the command has it); otherwise only a near spelling is
105
+ offered, so a short option is never pointed at an unrelated one (`--from` at `--full`).
106
+ Previously such an option was accepted and ignored, so a call that
102
107
  looked like it had filtered or narrowed a result was in fact answering the unfiltered
103
108
  question — and nothing in the output said so. Both spellings of an option work
104
109
  (`--run-id` and `--runId`), as they always did. The error's `fix` names the exact call
@@ -1333,7 +1338,7 @@ Shared flags: `--days <n>` (default 30) or `--start-date` / `--end-date` (`YYYY-
1333
1338
 
1334
1339
  `--measure` decides whose activity is measured and defaults to `campaigns` (only visitors a Baker landing brought). `--measure all` measures the client's entire website and is a decision somebody has to ask for. `host` is the client's own landing domain when one shares a domain with the site being measured, so the script and its events stay first-party; `firstParty` in the response says which, and removing that domain from Baker means re-running this command.
1335
1340
 
1336
- **Paging the list reports.** `people`, `submissions` and `delivery` are lists of individual things rather than breakdowns — `delivery` and `submissions` are the ones the CLI exposes, `people` backs the People section of the dashboard's landing Analytics screen over the same wire — and only they take `--page <n>` (1-based) and `--page-size <n>` (up to 200, default 50). The response carries `pageInfo` with `hasMore` — when it is true there **are** more rows, so a total must never be reported from one page. Pass neither flag and a list comes back at the size it always did.
1341
+ **Paging the list reports.** `people`, `submissions` and `delivery` are lists of individual things rather than breakdowns — `delivery` and `submissions` are the ones the CLI exposes, `people` backs the People section of the dashboard's landing Analytics screen over the same wire — and only they take `--page <n>` (1-based) and `--page-size <n>` (up to 200, default 50). The response carries `pageInfo` with `hasMore` — when it is true there **are** more rows, so a total must never be reported from one page. Pass neither flag and a list comes back at the size it always did. A value that is not a whole positive number (`--page /pricing`) is refused before any request, naming `--landing` as the flag that narrows a report to one page of the site.
1337
1342
 
1338
1343
  **A conversion is a company-level named event, not a property of a Form.** `baker analytics conversions` is the only place "what counts" is decided, and an empty `definitions` list means every conversion number in every other report is zero — not because nobody converted, but because nothing is named as an outcome and Baker never guesses which event is the point of a page. `--candidates` lists every event these pages actually produced — each Form step and trigger, every `data-baker-*` event, every outbound destination — with volume and whether it is already counted; that list is where an event key comes from, so never invent one. `--event <key> --name "Booked a call"` starts counting it **immediately and retroactively**: the whole stored history is rescored, so naming the right event today also fixes last month. Nothing here is staged and publishing is not involved. Two events given the same `--name` become one row and one number, which is how a call booked on three different Forms reads as one outcome. `--count-mode every_time` is for the outcomes people genuinely repeat (a guide downloaded twice is two downloads); the default counts once per visit.
1339
1344
 
package/dist/cli.js CHANGED
@@ -33563,6 +33563,19 @@ function pageOf(args5) {
33563
33563
  ...size ? { pageSize: Number(size) } : {}
33564
33564
  };
33565
33565
  }
33566
+ function isWholePositive(raw) {
33567
+ return /^[1-9]\d*$/.test(String(raw));
33568
+ }
33569
+ function paginationError(args5) {
33570
+ if (args5.page !== void 0 && !isWholePositive(args5.page)) {
33571
+ return `--page takes a page number of a list report (1, 2, \u2026), not "${String(args5.page)}". To narrow a report to one page of the site, pass --landing <internalId> (from \`baker analytics landings\`), or read one path with \`baker analytics page --path /pricing\`.`;
33572
+ }
33573
+ const size = args5["page-size"];
33574
+ if (size !== void 0 && !isWholePositive(size)) {
33575
+ return `--page-size takes a number of rows (1 to 200), not "${String(size)}".`;
33576
+ }
33577
+ return null;
33578
+ }
33566
33579
  function requestBody(args5, options) {
33567
33580
  const candidates = {
33568
33581
  preset: options.preset,
@@ -33627,6 +33640,11 @@ async function runPreset(args5, options) {
33627
33640
  });
33628
33641
  process.exit(1);
33629
33642
  }
33643
+ const pagination = paginationError(args5);
33644
+ if (pagination) {
33645
+ writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message: pagination } });
33646
+ process.exit(1);
33647
+ }
33630
33648
  try {
33631
33649
  const response = await apiPost("/api/analytics/query", requestBody(args5, options));
33632
33650
  const requestedPlatform = args5.platform === void 0 ? "" : String(args5.platform);
@@ -68772,19 +68790,36 @@ function findUnknownFlags(root, argv) {
68772
68790
  }
68773
68791
  return unknown;
68774
68792
  }
68793
+ var SYNONYMS = {
68794
+ from: ["start-date", "start", "since"],
68795
+ since: ["start-date", "start"],
68796
+ start: ["start-date", "since"],
68797
+ to: ["end-date", "end", "until"],
68798
+ until: ["end-date", "end"],
68799
+ end: ["end-date", "until"],
68800
+ path: ["landing"],
68801
+ url: ["landing"]
68802
+ };
68775
68803
  function closestFlag(unknown, command) {
68776
68804
  const accepted = acceptedNames(command);
68777
68805
  if (!accepted) {
68778
68806
  return null;
68779
68807
  }
68780
68808
  const name = unknown.replace(/^--/, "").split("=")[0] ?? "";
68809
+ const synonym = SYNONYMS[name]?.find((candidate) => accepted.has(candidate));
68810
+ if (synonym) {
68811
+ return `--${synonym}`;
68812
+ }
68781
68813
  const scored = [...accepted].filter((candidate) => !ALWAYS_ACCEPTED.has(candidate)).map((candidate) => ({
68782
68814
  candidate,
68783
68815
  prefix: sharedPrefix(name, candidate),
68784
68816
  distance: editDistance(name, candidate)
68785
- })).filter(({ prefix, distance }) => prefix >= 4 || distance <= 3).sort((a, b) => b.prefix - a.prefix || a.distance - b.distance);
68817
+ })).filter(({ prefix, distance }) => prefix >= 4 || distance <= typoBudget(name)).sort((a, b) => b.prefix - a.prefix || a.distance - b.distance);
68786
68818
  return scored[0] ? `--${scored[0].candidate}` : null;
68787
68819
  }
68820
+ function typoBudget(name) {
68821
+ return Math.max(1, Math.floor(name.length / 3));
68822
+ }
68788
68823
  function sharedPrefix(a, b) {
68789
68824
  let i = 0;
68790
68825
  while (i < a.length && i < b.length && a[i] === b[i]) {
@@ -68808,6 +68843,24 @@ function commandFor(root, argv) {
68808
68843
  const { command, resolved } = resolveCommand2(root, argv);
68809
68844
  return resolved ? command : null;
68810
68845
  }
68846
+ function suggestFlag(unknown, command) {
68847
+ const flag = closestFlag(unknown, command);
68848
+ if (!flag) {
68849
+ return null;
68850
+ }
68851
+ const args5 = argsOf(command) ?? {};
68852
+ const name = flag.slice(2);
68853
+ const def = args5[name] ?? args5[camel(name)];
68854
+ const described = def && typeof def === "object" ? def.description : void 0;
68855
+ const description = typeof described === "string" ? described.split(/(?<!\b(?:e\.g|i\.e|vs))\.\s/)[0]?.trim().replace(/\.$/, "") : "";
68856
+ return description ? { flag, description } : { flag };
68857
+ }
68858
+ function suggestionText(suggestion) {
68859
+ if (!suggestion) {
68860
+ return "";
68861
+ }
68862
+ return suggestion.description ? `Did you mean ${suggestion.flag}? It is described as: ${suggestion.description}. ` : `Did you mean ${suggestion.flag}? `;
68863
+ }
68811
68864
  var OUTPUT_EXPLANATION = "This command has no --output option: `--output json` is accepted by every command that prints the JSON envelope, and md or files only where `baker schema` lists `output`. Drop the option and read the default output. ";
68812
68865
  function unknownFlagEnvelope(unknown, commandPath, suggestion, hasSchema) {
68813
68866
  const list = unknown.join(", ");
@@ -68818,7 +68871,7 @@ function unknownFlagEnvelope(unknown, commandPath, suggestion, hasSchema) {
68818
68871
  message: `${list} ${unknown.length > 1 ? "are not options" : "is not an option"} of \`baker ${commandPath}\`.`,
68819
68872
  fix: {
68820
68873
  action: hasSchema ? "check_schema" : "check_help",
68821
- explanation: (unknown.some((flag) => flag === "--output" || flag.startsWith("--output=")) ? OUTPUT_EXPLANATION : "") + (suggestion ? `Did you mean ${suggestion}? ` : "") + `Run \`${hasSchema ? `baker schema ${commandPath}` : `baker ${commandPath} --help`}\` to see every option this command takes. Do not re-run the same call: until this version an unrecognised option was accepted and ignored, so a command that looked like it had filtered or narrowed the result was in fact answering the unfiltered question.`
68874
+ explanation: (unknown.some((flag) => flag === "--output" || flag.startsWith("--output=")) ? OUTPUT_EXPLANATION : "") + suggestionText(suggestion) + `Run \`${hasSchema ? `baker schema ${commandPath}` : `baker ${commandPath} --help`}\` to see every option this command takes. Do not re-run the same call: until this version an unrecognised option was accepted and ignored, so a command that looked like it had filtered or narrowed the result was in fact answering the unfiltered question.`
68822
68875
  },
68823
68876
  retryable: false
68824
68877
  }
@@ -68848,7 +68901,7 @@ function refuseUnknownFlags(root, argv) {
68848
68901
  }
68849
68902
  const command = commandFor(root, argv);
68850
68903
  const first = unknown[0];
68851
- const suggestion = command && first ? closestFlag(first, command) : null;
68904
+ const suggestion = command && first ? suggestFlag(first, command) : null;
68852
68905
  const path48 = commandPathOf(root, argv);
68853
68906
  process.stdout.write(
68854
68907
  `${JSON.stringify(unknownFlagEnvelope(unknown, path48, suggestion, findSchema(path48.split(" ")) !== void 0), null, 2)}