@koda-sl/baker-cli 0.295.1 → 0.296.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 +10 -0
- package/dist/cli.js +209 -18
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1268,6 +1268,9 @@ baker analytics conversions --event page:a --count-mode every_time # re
|
|
|
1268
1268
|
baker analytics conversions --rename "Lead form" --to "Lead" # merge two into one row
|
|
1269
1269
|
baker analytics conversions --remove page:request_demo
|
|
1270
1270
|
baker analytics conversions --remove-name "Lead"
|
|
1271
|
+
baker analytics sites # the websites the measurement tag is accepted from
|
|
1272
|
+
baker analytics sites --add example.com # and every subdomain of it — applies at once, no publish
|
|
1273
|
+
baker analytics website-tag # the tag for a site Baker does not publish, with the key in it
|
|
1271
1274
|
baker analytics delivery --page 2 # the next page of a long list
|
|
1272
1275
|
baker analytics submissions --flow contact # every attempt at a Form, delivered or not
|
|
1273
1276
|
```
|
|
@@ -1280,6 +1283,13 @@ Shared flags: `--days <n>` (default 30) or `--start-date` / `--end-date` (`YYYY-
|
|
|
1280
1283
|
- The `sparkline` on `landings` is dropped unless `--full`, and resampled to 30 points when present. It is bucketed by `--granularity` upstream, so ninety days at `hour` is 2,160 numbers per page.
|
|
1281
1284
|
- Past ~25 rows the response carries a hint naming the row count and pointing at `--output md`.
|
|
1282
1285
|
|
|
1286
|
+
**Measuring a website Baker does not publish.** `baker analytics website-tag` returns the tag with this company's site key in it, the websites it is accepted from, and the whole install as Markdown. Two things decide whether it does anything:
|
|
1287
|
+
|
|
1288
|
+
- **`baker analytics sites` first.** The key is public and is **silently ignored** from any origin not on the declared list, so a tag on an undeclared website is a perfect install that measures nothing, with no failing request anywhere. `--add` / `--remove` are repeatable, apply immediately, need no publish, and a tag already installed starts being accepted at once. Declare the **domain**, not the subdomain you happen to be installing on: one entry covers everything under it (`example.com` answers for `www.`, `go.` and `shop.eu.`) and it never widens upward. The response also carries `suggestedOrigins` — domains Baker already serves this company's landings on that nothing covers yet.
|
|
1289
|
+
- **The snippet is two scripts and both are required.** The first creates `window.baker` synchronously and queues calls; the second is the tag, which is async. Paste only the second and any outcome reported before it finishes loading reaches nothing — which on a thank-you page is the normal case. For the same reason, never guard a call with `if (!window.baker) return`: on the fastest pages that is always true, and it throws the conversion away with no error anywhere. Call `window.baker.track(…)` directly.
|
|
1290
|
+
|
|
1291
|
+
`--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.
|
|
1292
|
+
|
|
1283
1293
|
**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.
|
|
1284
1294
|
|
|
1285
1295
|
**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.
|
package/dist/cli.js
CHANGED
|
@@ -13327,10 +13327,52 @@ function mappingCommandFor(platform, proposed) {
|
|
|
13327
13327
|
|
|
13328
13328
|
// ../api/src/analytics/websiteTag.ts
|
|
13329
13329
|
import { z as z27 } from "zod";
|
|
13330
|
+
var websiteTagRequestSchema = z27.object({
|
|
13331
|
+
measure: z27.enum(["campaigns", "outcomes", "all"]).optional()
|
|
13332
|
+
});
|
|
13333
|
+
var analyticsSitesRequestSchema = z27.object({
|
|
13334
|
+
add: z27.array(z27.string()).optional(),
|
|
13335
|
+
remove: z27.array(z27.string()).optional()
|
|
13336
|
+
});
|
|
13337
|
+
var analyticsSitesResponseSchema = z27.object({
|
|
13338
|
+
/** Every declared website after the change, which is the answer to a bare read. */
|
|
13339
|
+
origins: z27.array(z27.string()),
|
|
13340
|
+
/** Normalized and actually new — an entry already present is reported in neither list. */
|
|
13341
|
+
added: z27.array(z27.string()),
|
|
13342
|
+
removed: z27.array(z27.string()),
|
|
13343
|
+
/** Still-undeclared domains this company owns. See {@link suggestedPixelOrigins}. */
|
|
13344
|
+
suggestedOrigins: z27.array(z27.string())
|
|
13345
|
+
});
|
|
13330
13346
|
var websiteTagResponseSchema = z27.object({
|
|
13331
13347
|
host: z27.string(),
|
|
13332
13348
|
siteKey: z27.string(),
|
|
13333
13349
|
origins: z27.array(z27.string()),
|
|
13350
|
+
/** Echoed back, so a caller that asked for nothing can see what it got. */
|
|
13351
|
+
measure: z27.enum(["campaigns", "outcomes", "all"]),
|
|
13352
|
+
/**
|
|
13353
|
+
* Whether `campaigns` scope can recognise anybody here — see
|
|
13354
|
+
* {@link campaignsScopeCanMatch}. `false` means the default measures nobody
|
|
13355
|
+
* on this company's install, however correctly the tag is pasted.
|
|
13356
|
+
*/
|
|
13357
|
+
campaignsCanMatch: z27.boolean(),
|
|
13358
|
+
/**
|
|
13359
|
+
* Whether `host` is one of the company's own domains rather than Baker's.
|
|
13360
|
+
*
|
|
13361
|
+
* Worth answering because it is the difference between an install a content
|
|
13362
|
+
* blocker removes and one it has no list entry for — the pixel takes its
|
|
13363
|
+
* collect endpoint from its own `src`, so this decides the fate of the event
|
|
13364
|
+
* stream and not just the script load. See {@link pixelHost}.
|
|
13365
|
+
*/
|
|
13366
|
+
firstParty: z27.boolean(),
|
|
13367
|
+
/**
|
|
13368
|
+
* Websites this company plainly owns and has not declared — the registrable
|
|
13369
|
+
* domains of its own landing domains. See {@link suggestedPixelOrigins}.
|
|
13370
|
+
*
|
|
13371
|
+
* A suggestion for somebody to accept, never a scope already granted: nothing
|
|
13372
|
+
* in Baker reads this list, and `baker analytics sites --add` is what acts on
|
|
13373
|
+
* it.
|
|
13374
|
+
*/
|
|
13375
|
+
suggestedOrigins: z27.array(z27.string()),
|
|
13334
13376
|
tag: z27.string(),
|
|
13335
13377
|
tagManagerTag: z27.string(),
|
|
13336
13378
|
brief: z27.string()
|
|
@@ -13548,6 +13590,7 @@ var analyticsPresetSchema = z28.enum([
|
|
|
13548
13590
|
"stream"
|
|
13549
13591
|
]);
|
|
13550
13592
|
var ANALYTICS_PRESETS = analyticsPresetSchema.options;
|
|
13593
|
+
var ANALYTICS_EVENT_DOORS = ["pages", "website", "server"];
|
|
13551
13594
|
var analyticsQueryRequestSchema = z28.object({
|
|
13552
13595
|
preset: analyticsPresetSchema,
|
|
13553
13596
|
/** Lookback in days. Ignored when `startDate` is given. */
|
|
@@ -13606,9 +13649,7 @@ var analyticsQueryRequestSchema = z28.object({
|
|
|
13606
13649
|
*/
|
|
13607
13650
|
adPlatform: z28.enum(AD_PLATFORMS).optional(),
|
|
13608
13651
|
/**
|
|
13609
|
-
* Read only what
|
|
13610
|
-
* measured itself, `systems` for what a client's own server posted to
|
|
13611
|
-
* `POST /v1/events`.
|
|
13652
|
+
* Read only what came in by one door. See {@link ANALYTICS_EVENT_DOORS}.
|
|
13612
13653
|
*
|
|
13613
13654
|
* Omit it for all of it, which is the default and the honest superset.
|
|
13614
13655
|
* Only the reads where the split is a question somebody asks honour it —
|
|
@@ -13617,7 +13658,7 @@ var analyticsQueryRequestSchema = z28.object({
|
|
|
13617
13658
|
* ingest row carries no `session_id`, deliberately, so there is no visit
|
|
13618
13659
|
* for it to be counted in.
|
|
13619
13660
|
*/
|
|
13620
|
-
eventOrigin: z28.enum(
|
|
13661
|
+
eventOrigin: z28.enum(ANALYTICS_EVENT_DOORS).optional(),
|
|
13621
13662
|
/**
|
|
13622
13663
|
* `stream` only: keep just one kind of event, named by the key
|
|
13623
13664
|
* `conversions` hands back in its catalogue.
|
|
@@ -14399,6 +14440,17 @@ var analyticsTimelineRowSchema = z28.object({
|
|
|
14399
14440
|
eventType: z28.string(),
|
|
14400
14441
|
/** `edge`, `beacon`, `server` — where the row was written from. */
|
|
14401
14442
|
source: z28.string(),
|
|
14443
|
+
/**
|
|
14444
|
+
* `baker`, `external`, `export` — where the page was, which `source` does
|
|
14445
|
+
* not say. The two together are what decide the row's door; see
|
|
14446
|
+
* `ANALYTICS_EVENT_DOORS`.
|
|
14447
|
+
*
|
|
14448
|
+
* Defaulted rather than required: the column arrived after the corpus did
|
|
14449
|
+
* and carries no default of its own, so a row older than it reads `""`, and
|
|
14450
|
+
* that has to mean "Baker's, as everything was then" rather than fail the
|
|
14451
|
+
* whole row's parse.
|
|
14452
|
+
*/
|
|
14453
|
+
deployment: z28.string().default(""),
|
|
14402
14454
|
environment: z28.string(),
|
|
14403
14455
|
/** The build the page was published from. */
|
|
14404
14456
|
release: z28.string(),
|
|
@@ -27956,7 +28008,7 @@ one marked "Already counted", so a retry is visible without being counted.
|
|
|
27956
28008
|
|
|
27957
28009
|
The same holds **across connections**, which is the reason to use it. If the page also
|
|
27958
28010
|
reports this outcome with Baker's website tag, pass one string as \`event_id\` here and as
|
|
27959
|
-
\`eventId\` in \`window.baker.
|
|
28011
|
+
\`eventId\` in \`window.baker.track(name, { eventId })\`: the browser event and the
|
|
27960
28012
|
server event are then one event and count once, whichever arrives first and whether or not
|
|
27961
28013
|
the other ever does. Report an important outcome from both \u2014 a browser can be blocked, a
|
|
27962
28014
|
server cannot \u2014 and always pair them with an id. Send no id and the two are two conversions,
|
|
@@ -28689,7 +28741,7 @@ function adHierarchyHints(data, platform) {
|
|
|
28689
28741
|
}
|
|
28690
28742
|
function sessionlessHint(data, origin) {
|
|
28691
28743
|
if (data.totals.pageViews === 0 || data.totals.sessions > 0) return [];
|
|
28692
|
-
if (origin === "
|
|
28744
|
+
if (origin === "server") {
|
|
28693
28745
|
return [
|
|
28694
28746
|
"No sessions, because this report is scoped to events a client's own server posted and those carry no visit \u2014 a session would be an invented one. Every per-visitor rate here is null for the same reason; read the counts, and drop --origin for anything about behaviour."
|
|
28695
28747
|
];
|
|
@@ -29045,6 +29097,73 @@ function formatHint(data, format) {
|
|
|
29045
29097
|
];
|
|
29046
29098
|
}
|
|
29047
29099
|
|
|
29100
|
+
// src/commands/analytics/websiteTagHints.ts
|
|
29101
|
+
function asTyped(origin) {
|
|
29102
|
+
return origin.replace(/^https?:\/\//, "");
|
|
29103
|
+
}
|
|
29104
|
+
function suggestionHint(suggested) {
|
|
29105
|
+
if (suggested.length === 0) return [];
|
|
29106
|
+
const commands = suggested.map((origin) => `baker analytics sites --add ${asTyped(origin)}`).join(" \xB7 ");
|
|
29107
|
+
return [
|
|
29108
|
+
`Baker publishes landing pages on ${suggested.map(asTyped).join(", ")} for this company, and no declared website covers ${suggested.length === 1 ? "it" : "them"}. Declaring the domain covers every subdomain of it \u2014 the marketing site, the shop, the booking page, and the ones that do not exist yet: ${commands}`
|
|
29109
|
+
];
|
|
29110
|
+
}
|
|
29111
|
+
function websiteTagHints(response) {
|
|
29112
|
+
const hints2 = [];
|
|
29113
|
+
if (response.origins.length === 0) {
|
|
29114
|
+
hints2.push(
|
|
29115
|
+
"NO WEBSITE DECLARED \u2014 this tag will be ignored everywhere it is installed, silently, with no failing request to find. Declare the site before installing anything: baker analytics sites --add <the client's domain>. It takes effect at once and needs no republish."
|
|
29116
|
+
);
|
|
29117
|
+
}
|
|
29118
|
+
hints2.push(...suggestionHint(response.suggestedOrigins));
|
|
29119
|
+
if (response.firstParty) {
|
|
29120
|
+
hints2.push(
|
|
29121
|
+
`This tag loads from ${response.host} \u2014 the client's own domain, not Baker's \u2014 so the script and every event it sends travel first-party, which a content blocker has no list entry for. The trade is a dependency: if that domain is ever removed from Baker, this tag 404s and measurement stops. Re-run this command after any domain change.`
|
|
29122
|
+
);
|
|
29123
|
+
}
|
|
29124
|
+
if (response.measure === "all") {
|
|
29125
|
+
hints2.push(
|
|
29126
|
+
"This tag measures the client's WHOLE WEBSITE \u2014 every visitor and every page view, not only the people your campaigns brought. Their reports will describe their business rather than their campaigns, and outcomes their site produces from organic, email and direct traffic will land in their conversion numbers. Only correct if somebody asked for that; otherwise re-run without --measure."
|
|
29127
|
+
);
|
|
29128
|
+
}
|
|
29129
|
+
if (response.measure === "campaigns" && !response.campaignsCanMatch) {
|
|
29130
|
+
hints2.push(
|
|
29131
|
+
"THIS TAG WILL MEASURE NOBODY \u2014 and will look installed. `campaigns` scope recognises a visitor by a first-party cookie, and a browser does not carry one between two different registrable domains. This company's landings are not on a subdomain of the site this tag goes on, so no visitor can ever match. Two fixes: put the landings on a subdomain of the client's own domain (a custom domain in Baker), or install with --measure outcomes, which measures no browsing and reports the outcomes the site tells Baker about."
|
|
29132
|
+
);
|
|
29133
|
+
} else if (response.measure === "campaigns") {
|
|
29134
|
+
hints2.push(
|
|
29135
|
+
"This tag measures only visitors who have been on one of this company's Baker landing pages \u2014 their whole journey through the site, to the outcome. Anybody else is not measured at all. Use --measure all only if the client asked for their whole website measured."
|
|
29136
|
+
);
|
|
29137
|
+
}
|
|
29138
|
+
hints2.push(
|
|
29139
|
+
'Reporting an outcome is not the same as counting it. After a `window.baker.track("name")` call is live, name it with: baker analytics conversions --event page:<name> --name "<what to call it>". That applies immediately and counts everything already collected.'
|
|
29140
|
+
);
|
|
29141
|
+
return hints2;
|
|
29142
|
+
}
|
|
29143
|
+
function analyticsSitesHints(response) {
|
|
29144
|
+
const hints2 = [];
|
|
29145
|
+
if (response.origins.length === 0) {
|
|
29146
|
+
hints2.push(
|
|
29147
|
+
"No website is declared, so this company's measurement tag is ignored wherever it is installed \u2014 silently, with no failing request to find. Add one with: baker analytics sites --add <the client's domain>"
|
|
29148
|
+
);
|
|
29149
|
+
}
|
|
29150
|
+
hints2.push(...suggestionHint(response.suggestedOrigins));
|
|
29151
|
+
if (response.added.length > 0) {
|
|
29152
|
+
hints2.push(
|
|
29153
|
+
`Live now. A tag already installed on ${response.added.map(asTyped).join(", ")} starts being accepted immediately \u2014 there is no new tag to paste and nothing to publish. Only events sent from here on are kept; the ones refused before this were never stored and cannot be recovered.`
|
|
29154
|
+
);
|
|
29155
|
+
}
|
|
29156
|
+
if (response.removed.length > 0) {
|
|
29157
|
+
hints2.push(
|
|
29158
|
+
`Measurement from ${response.removed.map(asTyped).join(", ")} will stop at once, with no error on that site \u2014 a tag still installed there goes quiet. Everything already collected from it is kept.`
|
|
29159
|
+
);
|
|
29160
|
+
}
|
|
29161
|
+
hints2.push(
|
|
29162
|
+
"One entry covers everything under it: example.com answers for www., go. and shop.eu. It never widens upward, so declaring go.example.com leaves example.com uncovered \u2014 declare the domain, not the subdomain you are installing on today."
|
|
29163
|
+
);
|
|
29164
|
+
return hints2;
|
|
29165
|
+
}
|
|
29166
|
+
|
|
29048
29167
|
// src/commands/analytics/index.ts
|
|
29049
29168
|
var SHARED_ARGS = {
|
|
29050
29169
|
days: { type: "string", description: "Lookback window in days (default: 30)", required: false },
|
|
@@ -29102,7 +29221,7 @@ var SHARED_ARGS = {
|
|
|
29102
29221
|
},
|
|
29103
29222
|
origin: {
|
|
29104
29223
|
type: "string",
|
|
29105
|
-
description: "Read one
|
|
29224
|
+
description: "Read one door only: `pages` for a browser on a page Baker publishes, `website` for a browser on the client's OWN website (the measurement tag), `server` for what their server posted to POST /v1/events. Omit it for all three, which is the default and the honest superset. Reach for it when a number moved and nothing on the pages changed \u2014 a CRM replaying history and a tag on the client's own site both land in the same totals as a landing page visitor, and this is the only thing that separates them. Honoured by overview, traffic, events and conversions; every session-scoped report ignores it, because a server-sent event carries no visit to be counted in",
|
|
29106
29225
|
required: false
|
|
29107
29226
|
},
|
|
29108
29227
|
output: {
|
|
@@ -29167,7 +29286,7 @@ function requestBody(args, options) {
|
|
|
29167
29286
|
Object.entries(candidates).filter(([key, value]) => value !== void 0 && (value !== "" || key === "adValue"))
|
|
29168
29287
|
);
|
|
29169
29288
|
}
|
|
29170
|
-
var EVENT_ORIGINS =
|
|
29289
|
+
var EVENT_ORIGINS = ANALYTICS_EVENT_DOORS;
|
|
29171
29290
|
async function runPreset(args, options) {
|
|
29172
29291
|
const origin = args.origin === void 0 ? "" : String(args.origin);
|
|
29173
29292
|
if (origin !== "" && !EVENT_ORIGINS.includes(origin)) {
|
|
@@ -29175,7 +29294,7 @@ async function runPreset(args, options) {
|
|
|
29175
29294
|
ok: false,
|
|
29176
29295
|
error: {
|
|
29177
29296
|
code: "VALIDATION_ERROR",
|
|
29178
|
-
message: `Unknown --origin "${origin}". Use one of: ${EVENT_ORIGINS.join(", ")}, or omit it for
|
|
29297
|
+
message: `Unknown --origin "${origin}". Use one of: ${EVENT_ORIGINS.join(", ")}, or omit it for all three.`
|
|
29179
29298
|
}
|
|
29180
29299
|
});
|
|
29181
29300
|
process.exit(1);
|
|
@@ -29773,7 +29892,13 @@ var websiteTagCommand = (() => {
|
|
|
29773
29892
|
registerSchema({
|
|
29774
29893
|
command: "analytics.website-tag",
|
|
29775
29894
|
description: "The measurement tag for a website Baker does not publish, with this company's key in it",
|
|
29776
|
-
args: {
|
|
29895
|
+
args: {
|
|
29896
|
+
measure: {
|
|
29897
|
+
type: "string",
|
|
29898
|
+
required: false,
|
|
29899
|
+
description: 'Whose activity to measure: "campaigns" (default), "outcomes" or "all"'
|
|
29900
|
+
}
|
|
29901
|
+
}
|
|
29777
29902
|
});
|
|
29778
29903
|
return defineCommand95({
|
|
29779
29904
|
meta: {
|
|
@@ -29785,16 +29910,81 @@ Reach for it whenever measurement has to reach a page Baker did not build. What
|
|
|
29785
29910
|
Three things worth knowing before you install it:
|
|
29786
29911
|
the origins list \u2014 the key is IGNORED from any origin not on it, silently. An empty list means the tag will measure nothing.
|
|
29787
29912
|
Tag Manager is usually the way in \u2014 a Custom HTML tag on All Pages. If the client has a container connected, you can stage that yourself (baker tag-manager).
|
|
29788
|
-
in a container, use tagManagerTag
|
|
29913
|
+
in a container, use tagManagerTag \u2014 the response carries two tags. \`tag\` is for a page somebody can edit; \`tagManagerTag\` is the one to stage, because a container rebuilds a Custom HTML tag's script element from its src alone and drops the key, so \`tag\` measures nothing there, published and silent. Check it on the page afterwards: window.baker in the browser console.
|
|
29914
|
+
--measure decides the BILL \u2014 the tag goes on every page whatever you do; this decides whose activity is measured. Leave it alone unless the client asked for their whole website.
|
|
29915
|
+
|
|
29916
|
+
--measure campaigns (default) people your Baker campaigns brought to the site. Their whole journey, through to the outcome. Nobody else is measured at all.
|
|
29917
|
+
--measure outcomes nobody's browsing. Only what the site reports with window.baker.track(...), and forms it wired to Baker.
|
|
29918
|
+
--measure all every visitor and every page view of the whole website. Their reports then describe their business, not their campaigns, and outcomes from organic, email and direct land in their conversion numbers. A decision, never a default.
|
|
29789
29919
|
|
|
29790
29920
|
Examples:
|
|
29791
29921
|
baker analytics website-tag \u2014 the tag, the origins and the install brief
|
|
29792
|
-
baker analytics
|
|
29922
|
+
baker analytics website-tag --measure all \u2014 measure their whole website, because they asked for that
|
|
29923
|
+
baker analytics events --origin website \u2014 after it is live, what that website is reporting`
|
|
29793
29924
|
},
|
|
29794
|
-
args: {
|
|
29795
|
-
|
|
29925
|
+
args: {
|
|
29926
|
+
measure: {
|
|
29927
|
+
type: "string",
|
|
29928
|
+
description: 'Whose activity to measure: "campaigns" (default), "outcomes" or "all". Widening is a decision \u2014 see above.'
|
|
29929
|
+
}
|
|
29930
|
+
},
|
|
29931
|
+
run: async (ctx) => {
|
|
29932
|
+
try {
|
|
29933
|
+
const measure = typeof ctx.args.measure === "string" ? ctx.args.measure : void 0;
|
|
29934
|
+
const envelope = await apiPost(
|
|
29935
|
+
"/api/analytics/website-tag",
|
|
29936
|
+
measure ? { measure } : {}
|
|
29937
|
+
);
|
|
29938
|
+
writeJsonEnvelope({ ...envelope, hints: websiteTagHints(envelope.data) });
|
|
29939
|
+
} catch (err) {
|
|
29940
|
+
handleError(err);
|
|
29941
|
+
}
|
|
29942
|
+
}
|
|
29943
|
+
});
|
|
29944
|
+
})();
|
|
29945
|
+
var sitesCommand = (() => {
|
|
29946
|
+
registerSchema({
|
|
29947
|
+
command: "analytics.sites",
|
|
29948
|
+
description: "The websites this company's measurement tag is accepted from, and adding or removing one",
|
|
29949
|
+
args: {
|
|
29950
|
+
add: { type: "string", required: false, description: "Website address to accept measurement from" },
|
|
29951
|
+
remove: { type: "string", required: false, description: "Website address to stop accepting measurement from" }
|
|
29952
|
+
}
|
|
29953
|
+
});
|
|
29954
|
+
return defineCommand95({
|
|
29955
|
+
meta: {
|
|
29956
|
+
name: "sites",
|
|
29957
|
+
description: `Which websites this company's measurement tag is accepted from \u2014 and the command that changes it.
|
|
29958
|
+
|
|
29959
|
+
The site key ships in the source of every page it is pasted on, so this list is the whole of what stops a stranger who read it appending forged conversions to these numbers. A tag on a website that is NOT on this list is ignored, silently, with no failing request anywhere. That is the single most common reason an install measures nothing.
|
|
29960
|
+
|
|
29961
|
+
One entry covers the estate under it: example.com answers for www.example.com, go.example.com and shop.eu.example.com. It never widens upward \u2014 declaring go.example.com does NOT cover example.com \u2014 so declare the DOMAIN, not the subdomain you happen to be installing on today.
|
|
29962
|
+
|
|
29963
|
+
Start here:
|
|
29964
|
+
baker analytics sites \u2014 what is declared now, and what is worth adding
|
|
29965
|
+
baker analytics sites --add example.com \u2014 accept measurement from that site and everything under it
|
|
29966
|
+
baker analytics sites --remove old-site.com
|
|
29967
|
+
|
|
29968
|
+
Examples:
|
|
29969
|
+
baker analytics website-tag \u2014 get the tag; if its origins are empty, come here first
|
|
29970
|
+
baker analytics sites --add foodforjoe.es \u2014 one entry covering www., go. and shop.`
|
|
29971
|
+
},
|
|
29972
|
+
args: {
|
|
29973
|
+
add: {
|
|
29974
|
+
type: "string",
|
|
29975
|
+
description: "Website address to accept measurement from, e.g. example.com \u2014 covers every subdomain of it. Repeat for several"
|
|
29976
|
+
},
|
|
29977
|
+
remove: { type: "string", description: "Website address to stop accepting measurement from" }
|
|
29978
|
+
},
|
|
29979
|
+
run: async (ctx) => {
|
|
29796
29980
|
try {
|
|
29797
|
-
|
|
29981
|
+
const raw = ctx.rawArgs;
|
|
29982
|
+
const body = {
|
|
29983
|
+
add: repeatedValues(raw, "add", ctx.args.add),
|
|
29984
|
+
remove: repeatedValues(raw, "remove", ctx.args.remove)
|
|
29985
|
+
};
|
|
29986
|
+
const envelope = await apiPost("/api/analytics/sites", body);
|
|
29987
|
+
writeJsonEnvelope({ ...envelope, hints: analyticsSitesHints(envelope.data) });
|
|
29798
29988
|
} catch (err) {
|
|
29799
29989
|
handleError(err);
|
|
29800
29990
|
}
|
|
@@ -29844,7 +30034,7 @@ Examples:
|
|
|
29844
30034
|
baker analytics website-tag \u2014 the tag for a website Baker does not publish, key included
|
|
29845
30035
|
baker analytics sending-events \u2014 the contract for a client's server to post its own events
|
|
29846
30036
|
baker analytics arrivals --outcome rejected \u2014 what their server posted that we refused, and why
|
|
29847
|
-
baker analytics events --origin
|
|
30037
|
+
baker analytics events --origin server \u2014 the events their systems reported, not ours
|
|
29848
30038
|
Full guide: __tooling__/docs/tools/baker/analytics.md`
|
|
29849
30039
|
},
|
|
29850
30040
|
subCommands: {
|
|
@@ -29871,6 +30061,7 @@ Full guide: __tooling__/docs/tools/baker/analytics.md`
|
|
|
29871
30061
|
arrivals: arrivalsCommand,
|
|
29872
30062
|
"sending-events": sendingEventsCommand,
|
|
29873
30063
|
"website-tag": websiteTagCommand,
|
|
30064
|
+
sites: sitesCommand,
|
|
29874
30065
|
presets: presetsCommand
|
|
29875
30066
|
}
|
|
29876
30067
|
});
|
|
@@ -44166,7 +44357,7 @@ function siteHints(sites) {
|
|
|
44166
44357
|
resources: sites.map((site) => ({ id: site.siteUrl, label: site.permissionLevel }))
|
|
44167
44358
|
});
|
|
44168
44359
|
}
|
|
44169
|
-
var
|
|
44360
|
+
var sitesCommand2 = defineCommand134({
|
|
44170
44361
|
meta: {
|
|
44171
44362
|
name: "sites",
|
|
44172
44363
|
description: `List verified Search Console sites.
|
|
@@ -44231,7 +44422,7 @@ Examples:
|
|
|
44231
44422
|
Full guide: __tooling__/docs/tools/baker/gsc.md`
|
|
44232
44423
|
},
|
|
44233
44424
|
subCommands: {
|
|
44234
|
-
sites:
|
|
44425
|
+
sites: sitesCommand2,
|
|
44235
44426
|
query: queryCommand3,
|
|
44236
44427
|
sitemaps: sitemapsCommand
|
|
44237
44428
|
}
|