@koda-sl/baker-cli 0.313.0-dev.64ea8cd98 → 0.313.0-dev.ca75dc08a
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 +1 -1
- package/dist/cli.js +34 -13
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1382,7 +1382,7 @@ baker funnel --steps '[...]' # the whole funnel, restat
|
|
|
1382
1382
|
|
|
1383
1383
|
**Every write says what it dropped.** `--step` changes one step and leaves the rest as it stands; `--steps` replaces the whole funnel and `--preset` draws over it. Every write returns `removed[]` and a `REMOVED steps:` hint when a step went, so a restatement written from a stale read is caught in the same turn.
|
|
1384
1384
|
|
|
1385
|
-
**A step says what triggers it, and every trigger is PICKED from `--moments`.** `triggers` is a list and any one of them firing is enough. Three kinds: `{"kind":"event","eventKey":"submit:contact"}` for anything the company's Forms, pages or systems produced (`moments.events`, `moments.sources`), `{"kind":"landing","landingId":"<id>"}` for one landing being viewed (`moments.landings`), and `{"kind":"any_landing"}` for any landing — what the default first step listens for. Nothing has to be named first: the event is used by its own key, and the step shows it by its own words. `moments.events[].origin` tells a page's event (`site`) from one the client's own systems sent (`systems`); `moments.sources` lists the client's systems by the `page:<name>` key each raises, pickable before the first send arrives. **A Form's own endings need nothing set up first** — no Source, no conversion: a Baker page raises them natively, so every Form in the workspace
|
|
1385
|
+
**A step says what triggers it, and every trigger is PICKED from `--moments`.** `triggers` is a list and any one of them firing is enough. Three kinds: `{"kind":"event","eventKey":"submit:contact"}` for anything the company's Forms, pages or systems produced (`moments.events`, `moments.sources`), `{"kind":"landing","landingId":"<id>"}` for one landing being viewed (`moments.landings`), and `{"kind":"any_landing"}` for any landing — what the default first step listens for. Nothing has to be named first: the event is used by its own key, and the step shows it by its own words. `moments.events[].origin` tells a page's event (`site`) from one the client's own systems sent (`systems`); `moments.sources` lists the client's systems by the `page:<name>` key each raises, pickable before the first send arrives. **A Form's own endings need nothing set up first** — no Source, no conversion: a Baker page raises them natively, so every Form in the workspace has its **outcome** marked in `moments.events` with `outcome: true` and the `step` it happens on — a Form nobody has filled in yet gets that row at zero, `seen: false`. It is the same ending `baker analytics conversions` recommends counting, so a step and a conversion land on the same event; `baker analytics conversions --flow <slug>` lists all of one Form's endings when a step wants another. `baker funnel` also hints, in one line, every workspace Form that reaches no step, with its outcome key. Place one with **`baker funnel --add-trigger <step-key> --event <key>`**, which adds a single way in and leaves the step's name, stage, `after[]` and other triggers untouched — `--step` takes a whole step and silently drops any trigger a restatement forgets. That is what makes a Form built minutes ago pickable. A key typed from memory saves, publishes and counts nobody forever — the hint "has a trigger and nobody reached it while N people entered" is that mistake caught after the fact. A step written with `offlineConversions`, a `conversion` trigger or an `analytics` trigger is refused before any round trip, with the shape to use.
|
|
1386
1386
|
|
|
1387
1387
|
**A landing being viewed can be a step** — where most funnels start — and never a conversion: `baker analytics conversions` refuses a `view:` key.
|
|
1388
1388
|
|
package/dist/cli.js
CHANGED
|
@@ -47238,28 +47238,37 @@ import { defineCommand as defineCommand129 } from "citty";
|
|
|
47238
47238
|
// src/commands/funnel/formMoments.ts
|
|
47239
47239
|
var MAX_NAMED_FORMS = 8;
|
|
47240
47240
|
function formMoments(events, forms) {
|
|
47241
|
-
const
|
|
47242
|
-
const rows = [];
|
|
47241
|
+
const outcomes = /* @__PURE__ */ new Map();
|
|
47243
47242
|
for (const form of forms) {
|
|
47244
47243
|
const outcome = suggestedEnding(flowEventKeys(form.tree, form.slug));
|
|
47245
|
-
if (outcome
|
|
47246
|
-
|
|
47247
|
-
|
|
47244
|
+
if (outcome !== null) outcomes.set(outcome.eventKey, { slug: form.slug, outcome });
|
|
47245
|
+
}
|
|
47246
|
+
const marked = events.map((event) => {
|
|
47247
|
+
const found = outcomes.get(event.eventKey);
|
|
47248
|
+
if (found === void 0) return event;
|
|
47249
|
+
outcomes.delete(event.eventKey);
|
|
47250
|
+
return { ...event, step: found.outcome.nodeName, outcome: true };
|
|
47251
|
+
});
|
|
47252
|
+
const unfired = [...outcomes.values()].map(
|
|
47253
|
+
({ slug, outcome }) => ({
|
|
47248
47254
|
eventKey: outcome.eventKey,
|
|
47249
47255
|
origin: "site",
|
|
47250
|
-
flowSlug:
|
|
47256
|
+
flowSlug: slug,
|
|
47251
47257
|
...outcome.nodeType === null ? {} : { nodeType: outcome.nodeType },
|
|
47252
47258
|
events: 0,
|
|
47253
47259
|
sessions: 0,
|
|
47254
47260
|
step: outcome.nodeName,
|
|
47255
47261
|
seen: false,
|
|
47256
47262
|
outcome: true
|
|
47257
|
-
})
|
|
47258
|
-
|
|
47259
|
-
return
|
|
47263
|
+
})
|
|
47264
|
+
);
|
|
47265
|
+
return [...marked, ...unfired];
|
|
47260
47266
|
}
|
|
47261
47267
|
function withFormMoments(moments, forms) {
|
|
47262
|
-
return { ...moments, events:
|
|
47268
|
+
return { ...moments, events: formMoments(moments.events, forms) };
|
|
47269
|
+
}
|
|
47270
|
+
function formsNamedHere(forms) {
|
|
47271
|
+
return forms.filter((form) => suggestedEnding(flowEventKeys(form.tree, form.slug)) !== null).map((form) => form.slug);
|
|
47263
47272
|
}
|
|
47264
47273
|
function unplacedFormHints(steps, forms) {
|
|
47265
47274
|
const onAStep = new Set(
|
|
@@ -47595,7 +47604,14 @@ var funnelRequestSchema = z44.object({
|
|
|
47595
47604
|
*/
|
|
47596
47605
|
moments: z44.boolean().optional(),
|
|
47597
47606
|
/** How many days the counts beside each step cover. Default 30. */
|
|
47598
|
-
days: z44.number().int().min(1).max(400).optional()
|
|
47607
|
+
days: z44.number().int().min(1).max(400).optional(),
|
|
47608
|
+
/**
|
|
47609
|
+
* The Forms, by slug, the caller names itself when no step counts them —
|
|
47610
|
+
* `baker funnel` reads its own workspace and names each with the key that
|
|
47611
|
+
* places it. The backend leaves them out of its own hint, so no Form is
|
|
47612
|
+
* named twice.
|
|
47613
|
+
*/
|
|
47614
|
+
namedByCaller: z44.array(z44.string().min(1).max(200)).max(1e3).optional()
|
|
47599
47615
|
});
|
|
47600
47616
|
var funnelResponseSchema = z44.object({
|
|
47601
47617
|
ok: z44.literal(true),
|
|
@@ -47943,7 +47959,7 @@ var args3 = {
|
|
|
47943
47959
|
},
|
|
47944
47960
|
moments: {
|
|
47945
47961
|
type: "boolean",
|
|
47946
|
-
description: "Also return everything a trigger can name, so a trigger is PICKED rather than invented: `events` (every event this company's Forms, pages and systems produced in the window, with volume, the Form it belongs to, `origin` \u2014 `site` for a page or Form, `systems` for the client's own server, `both` \u2014 and `countedAs` when the company also counts it as a page conversion, which a trigger does not need;
|
|
47962
|
+
description: "Also return everything a trigger can name, so a trigger is PICKED rather than invented: `events` (every event this company's Forms, pages and systems produced in the window, with volume, the Form it belongs to, `origin` \u2014 `site` for a page or Form, `systems` for the client's own server, `both` \u2014 and `countedAs` when the company also counts it as a page conversion, which a trigger does not need; with **each Form's OUTCOME in this workspace marked** `outcome: true` and the `step` it happens on \u2014 a Form nobody has filled in yet gets that row at zero, `seen: false`, so a Form built minutes ago is pickable with nothing set up first. It is the booking on a Form that books, the submit on a Form that submits, and it is the same ending `baker analytics conversions` recommends counting, so the step and the conversion land on the same event. One marked row and not all seven a Form raises: the rest are rarely what a step wants, and `baker analytics conversions --flow <slug>` lists every ending of one Form, fired or not), `sources` (the client's own systems that post events to Baker, by the `page:<name>` key each raises, pickable before its first send arrives) and `landings` (its pages, by the id a `landing` trigger takes). Use this before writing any `triggers`: a key typed from memory saves, publishes and counts nobody forever. A Form's events need NOTHING set up first \u2014 no Source, no conversion: a Baker page raises them by itself",
|
|
47947
47963
|
required: false
|
|
47948
47964
|
},
|
|
47949
47965
|
days: {
|
|
@@ -47971,8 +47987,13 @@ var funnelCommand2 = defineCommand129({
|
|
|
47971
47987
|
run: async ({ args: raw }) => {
|
|
47972
47988
|
try {
|
|
47973
47989
|
const parsed = parseFunnelArgs(raw);
|
|
47974
|
-
const response = await apiPost("/api/funnel", funnelWrite(parsed));
|
|
47975
47990
|
const forms = workspaceForms();
|
|
47991
|
+
const namedByCaller = formsNamedHere(forms);
|
|
47992
|
+
const request = {
|
|
47993
|
+
...funnelWrite(parsed),
|
|
47994
|
+
...namedByCaller.length === 0 ? {} : { namedByCaller }
|
|
47995
|
+
};
|
|
47996
|
+
const response = await apiPost("/api/funnel", request);
|
|
47976
47997
|
const data = response.data.moments === void 0 ? response.data : { ...response.data, moments: withFormMoments(response.data.moments, forms) };
|
|
47977
47998
|
const hints2 = [...response.hints ?? [], ...unplacedFormHints(response.data.steps ?? [], forms)];
|
|
47978
47999
|
writeJsonEnvelope({
|