@getvitops/utils 8.1.0 → 8.2.0-alpha.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/CHANGELOG.md +264 -8
- package/dist/{adc-BFrzpMHq.d.mts → adc-BoEoogyo.d.mts} +2 -3
- package/dist/adc-BoEoogyo.d.mts.map +1 -0
- package/dist/ads/index.d.mts +50 -17
- package/dist/ads/index.d.mts.map +1 -1
- package/dist/ads/index.mjs +75 -7
- package/dist/ads/index.mjs.map +1 -1
- package/dist/cloudflare-BiK61Oq4.d.mts.map +1 -1
- package/dist/color/index.d.mts +34 -35
- package/dist/color/index.d.mts.map +1 -1
- package/dist/color/index.mjs +3 -1
- package/dist/color/index.mjs.map +1 -1
- package/dist/crm/index.d.mts +288 -0
- package/dist/crm/index.d.mts.map +1 -0
- package/dist/crm/index.mjs +731 -0
- package/dist/crm/index.mjs.map +1 -0
- package/dist/email/index.d.mts +216 -0
- package/dist/email/index.d.mts.map +1 -0
- package/dist/email/index.mjs +331 -0
- package/dist/email/index.mjs.map +1 -0
- package/dist/favicon.d.mts +8 -9
- package/dist/favicon.d.mts.map +1 -1
- package/dist/git/index.d.mts +65 -0
- package/dist/git/index.d.mts.map +1 -0
- package/dist/git/index.mjs +107 -0
- package/dist/git/index.mjs.map +1 -0
- package/dist/hosting/index.d.mts +29 -29
- package/dist/hosting/index.d.mts.map +1 -1
- package/dist/hosting/index.mjs +7 -4
- package/dist/hosting/index.mjs.map +1 -1
- package/dist/identity-BoRddTx3.mjs +35 -0
- package/dist/identity-BoRddTx3.mjs.map +1 -0
- package/dist/index.d.mts +24 -25
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +5 -5
- package/dist/index.mjs.map +1 -1
- package/dist/indexing/index.d.mts +23 -24
- package/dist/indexing/index.d.mts.map +1 -1
- package/dist/media/index.d.mts +24 -24
- package/dist/media/index.d.mts.map +1 -1
- package/dist/media/index.mjs +3 -3
- package/dist/media/index.mjs.map +1 -1
- package/dist/notify/index.d.mts +26 -15
- package/dist/notify/index.d.mts.map +1 -1
- package/dist/notify/index.mjs +50 -20
- package/dist/notify/index.mjs.map +1 -1
- package/dist/onboarding/index.d.mts +10 -141
- package/dist/onboarding/index.d.mts.map +1 -1
- package/dist/onboarding/index.mjs +1 -144
- package/dist/onboarding/index.mjs.map +1 -1
- package/dist/plan-BLKikoOG.mjs +150 -0
- package/dist/plan-BLKikoOG.mjs.map +1 -0
- package/dist/plan-Hq8Pb0Uw.d.mts +133 -0
- package/dist/plan-Hq8Pb0Uw.d.mts.map +1 -0
- package/dist/reviews/index.d.mts +12 -13
- package/dist/reviews/index.d.mts.map +1 -1
- package/dist/schema/index.d.mts +7 -7
- package/dist/schema/index.d.mts.map +1 -1
- package/dist/security/index.d.mts +2 -2
- package/dist/security/index.d.mts.map +1 -1
- package/dist/{token-Bz_-igw-.d.mts → token-DmmoQ7um.d.mts} +6 -3
- package/dist/token-DmmoQ7um.d.mts.map +1 -0
- package/dist/tracking/index.d.mts +43 -17
- package/dist/tracking/index.d.mts.map +1 -1
- package/dist/tracking/index.mjs +2 -1
- package/dist/tracking/index.mjs.map +1 -1
- package/dist/{types-CHHjzRrv.d.mts → types-7ELci8RQ.d.mts} +4 -2
- package/dist/types-7ELci8RQ.d.mts.map +1 -0
- package/package.json +14 -4
- package/dist/adc-BFrzpMHq.d.mts.map +0 -1
- package/dist/token-Bz_-igw-.d.mts.map +0 -1
- package/dist/types-CHHjzRrv.d.mts.map +0 -1
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { t as table } from "./plan-format-A18SvJ7C.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/onboarding/plan.ts
|
|
4
|
+
/** The `sc-domain:` property identifier for a bare domain. */
|
|
5
|
+
const siteUrlFor = (domain) => `sc-domain:${domain}`;
|
|
6
|
+
/**
|
|
7
|
+
* Backoff ladder for the verification retry, in milliseconds.
|
|
8
|
+
*
|
|
9
|
+
* DNS_TXT verification fails until the record has propagated, which is a matter of
|
|
10
|
+
* seconds-to-minutes, not a real error — so the schedule is a *policy*, decided
|
|
11
|
+
* here and asserted in the tests, while the actual sleeping is the CLI's job.
|
|
12
|
+
* Capped at `maxAttempts`; a domain still unverified after the last attempt is
|
|
13
|
+
* reported PENDING, never failed.
|
|
14
|
+
*/
|
|
15
|
+
function backoffSchedule(maxAttempts = 5) {
|
|
16
|
+
const out = [];
|
|
17
|
+
for (let i = 1; i <= maxAttempts; i++) out.push(2 ** i * 1e3);
|
|
18
|
+
return out;
|
|
19
|
+
}
|
|
20
|
+
/** Decide the four steps for one domain from its desired config and live state. */
|
|
21
|
+
function planDomain(setup, state) {
|
|
22
|
+
const reminders = [];
|
|
23
|
+
if (setup.fullUserGroup) reminders.push(`add ${setup.fullUserGroup} as a Full User in Search Console — no API exists for this, do it in the UI`);
|
|
24
|
+
const txt = state.txtPresent ? {
|
|
25
|
+
action: "skip",
|
|
26
|
+
detail: "apex TXT already present"
|
|
27
|
+
} : {
|
|
28
|
+
action: "create",
|
|
29
|
+
detail: "create apex TXT verification record"
|
|
30
|
+
};
|
|
31
|
+
const verify = state.verified ? {
|
|
32
|
+
action: "skip",
|
|
33
|
+
detail: "ownership already verified"
|
|
34
|
+
} : {
|
|
35
|
+
action: "create",
|
|
36
|
+
detail: "verify ownership (DNS_TXT)"
|
|
37
|
+
};
|
|
38
|
+
const property = state.propertyExists ? {
|
|
39
|
+
action: "skip",
|
|
40
|
+
detail: "property already exists"
|
|
41
|
+
} : {
|
|
42
|
+
action: "create",
|
|
43
|
+
detail: `add property ${siteUrlFor(setup.domain)}`
|
|
44
|
+
};
|
|
45
|
+
const desired = setup.delegatedOwners ?? [];
|
|
46
|
+
const present = new Set(state.currentOwners.map((o) => o.toLowerCase()));
|
|
47
|
+
const ownersToAdd = desired.filter((o) => !present.has(o.toLowerCase()));
|
|
48
|
+
const owners = desired.length === 0 ? {
|
|
49
|
+
action: "skip",
|
|
50
|
+
detail: "no delegated owners"
|
|
51
|
+
} : ownersToAdd.length === 0 ? {
|
|
52
|
+
action: "skip",
|
|
53
|
+
detail: "all delegated owners already present"
|
|
54
|
+
} : {
|
|
55
|
+
action: "update",
|
|
56
|
+
detail: `add ${ownersToAdd.length} owner(s): ${ownersToAdd.join(", ")}`
|
|
57
|
+
};
|
|
58
|
+
return {
|
|
59
|
+
domain: setup.domain,
|
|
60
|
+
siteUrl: siteUrlFor(setup.domain),
|
|
61
|
+
txt,
|
|
62
|
+
verify,
|
|
63
|
+
property,
|
|
64
|
+
owners,
|
|
65
|
+
ownersToAdd,
|
|
66
|
+
reminders
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The owner set to PUT: everyone already there, plus everyone being added.
|
|
71
|
+
*
|
|
72
|
+
* `updateOwners` REPLACES the owner list, so this is the one computation standing
|
|
73
|
+
* between a delegation and locking yourself out — pass a bare `ownersToAdd` and
|
|
74
|
+
* the account that just verified the domain is removed from it. It belongs here
|
|
75
|
+
* rather than at the call site for exactly that reason: it is a decision, it is
|
|
76
|
+
* the dangerous one, and the executor is not allowed to make it.
|
|
77
|
+
*
|
|
78
|
+
* `current` comes FIRST so the API's own casing survives dedupe; matching is
|
|
79
|
+
* case-insensitive, mirroring `planDomain`'s `present` check, because Google
|
|
80
|
+
* echoes back addresses in whatever case the account uses and a case-sensitive
|
|
81
|
+
* `Set` would re-add an owner who is already there.
|
|
82
|
+
*/
|
|
83
|
+
function ownerUnion(current, toAdd) {
|
|
84
|
+
const out = [];
|
|
85
|
+
const seen = /* @__PURE__ */ new Set();
|
|
86
|
+
for (const o of [...current, ...toAdd]) {
|
|
87
|
+
const key = o.toLowerCase();
|
|
88
|
+
if (seen.has(key)) continue;
|
|
89
|
+
seen.add(key);
|
|
90
|
+
out.push(o);
|
|
91
|
+
}
|
|
92
|
+
return out;
|
|
93
|
+
}
|
|
94
|
+
/** Plan every domain. */
|
|
95
|
+
function plan(config, states) {
|
|
96
|
+
const notes = [];
|
|
97
|
+
return {
|
|
98
|
+
domains: config.domains.map((setup) => {
|
|
99
|
+
const state = states.get(setup.domain);
|
|
100
|
+
if (!state) notes.push(`${setup.domain}: no observed state; treating everything as pending`);
|
|
101
|
+
return planDomain(setup, state ?? {
|
|
102
|
+
txtPresent: false,
|
|
103
|
+
verified: false,
|
|
104
|
+
currentOwners: [],
|
|
105
|
+
propertyExists: false
|
|
106
|
+
});
|
|
107
|
+
}),
|
|
108
|
+
notes
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/** Any step on any domain is a mutation — i.e. the live state has drifted. */
|
|
112
|
+
function hasDrift(p) {
|
|
113
|
+
return p.domains.some((d) => d.txt.action !== "skip" || d.verify.action !== "skip" || d.property.action !== "skip" || d.owners.action !== "skip");
|
|
114
|
+
}
|
|
115
|
+
/** Render a plan as the block `--dry` and `--check` print. */
|
|
116
|
+
function formatPlan(p) {
|
|
117
|
+
const lines = [];
|
|
118
|
+
const glyph = (s) => s.action === "skip" ? "·" : "+";
|
|
119
|
+
for (const d of p.domains) {
|
|
120
|
+
lines.push(d.domain);
|
|
121
|
+
lines.push(` ${glyph(d.txt)} TXT ${d.txt.detail}`);
|
|
122
|
+
lines.push(` ${glyph(d.verify)} verify ${d.verify.detail}`);
|
|
123
|
+
lines.push(` ${glyph(d.property)} property ${d.property.detail}`);
|
|
124
|
+
lines.push(` ${glyph(d.owners)} owners ${d.owners.detail}`);
|
|
125
|
+
for (const r of d.reminders) lines.push(` ! ${r}`);
|
|
126
|
+
}
|
|
127
|
+
for (const n of p.notes) lines.push(`! ${n}`);
|
|
128
|
+
return lines.join("\n");
|
|
129
|
+
}
|
|
130
|
+
/** Render the end-of-run summary: one row per domain, plus any reminders. */
|
|
131
|
+
function formatSummary(results) {
|
|
132
|
+
const headers = [
|
|
133
|
+
"DOMAIN",
|
|
134
|
+
"TXT",
|
|
135
|
+
"VERIFIED",
|
|
136
|
+
"PROPERTY"
|
|
137
|
+
];
|
|
138
|
+
const rows = results.map((r) => [
|
|
139
|
+
r.domain,
|
|
140
|
+
r.txt,
|
|
141
|
+
r.verified,
|
|
142
|
+
r.property
|
|
143
|
+
]);
|
|
144
|
+
const reminders = results.flatMap((r) => r.reminders.map((m) => ` ! ${r.domain}: ${m}`));
|
|
145
|
+
return table(headers, rows, reminders);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
//#endregion
|
|
149
|
+
export { ownerUnion as a, siteUrlFor as c, hasDrift as i, formatPlan as n, plan as o, formatSummary as r, planDomain as s, backoffSchedule as t };
|
|
150
|
+
//# sourceMappingURL=plan-BLKikoOG.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-BLKikoOG.mjs","names":[],"sources":["../src/onboarding/plan.ts"],"sourcesContent":["/**\n * Every decision `vitops search setup` makes, as one pure function.\n *\n * Pure in the load-bearing sense: no `fetch`, no `fs`, no clock. The executors\n * beside this one gather each domain's live state and apply what they are told;\n * this module decides, from that state, what is left to do. That split is what\n * makes `--dry` a complete account of a run and `--check` an honest drift report —\n * the same arrangement the indexing planner makes against `gsc.ts`/`indexnow.ts`.\n *\n * Idempotency lives here too: a step whose desired state already holds resolves to\n * `skip`, so a re-run of a fully-onboarded domain is all skips — a no-op, by\n * construction rather than by the executors checking twice.\n */\nimport type { DomainSetup, DomainState, OnboardingConfig } from './types.ts';\nimport { table } from '../plan-format.ts';\n\n/** A step's decision: do it, or skip it because it already holds. */\nexport type StepAction = 'create' | 'update' | 'skip';\n\nexport interface StepPlan {\n action: StepAction;\n /** Why it's a skip, or what the mutation will do. */\n detail: string;\n}\n\n/** The four onboarding steps for one domain, decided against its live state. */\nexport interface DomainPlan {\n domain: string;\n /** `sc-domain:` property identifier this domain maps to. */\n siteUrl: string;\n /** Ensure the apex TXT verification record. */\n txt: StepPlan;\n /** Verify ownership via the Site Verification API (DNS_TXT). */\n verify: StepPlan;\n /** Add the Search Console domain property. */\n property: StepPlan;\n /** Add delegated owners to the verified web resource. */\n owners: StepPlan;\n /** Owners not yet present that the run should add. */\n ownersToAdd: string[];\n /** Manual follow-ups (e.g. a Full-User group). */\n reminders: string[];\n}\n\nexport interface OnboardingPlan {\n domains: DomainPlan[];\n /** Operator-facing warnings that span the whole run. */\n notes: string[];\n}\n\n/** The `sc-domain:` property identifier for a bare domain. */\nexport const siteUrlFor = (domain: string): string => `sc-domain:${domain}`;\n\n/**\n * Backoff ladder for the verification retry, in milliseconds.\n *\n * DNS_TXT verification fails until the record has propagated, which is a matter of\n * seconds-to-minutes, not a real error — so the schedule is a *policy*, decided\n * here and asserted in the tests, while the actual sleeping is the CLI's job.\n * Capped at `maxAttempts`; a domain still unverified after the last attempt is\n * reported PENDING, never failed.\n */\nexport function backoffSchedule(maxAttempts = 5): number[] {\n const out: number[] = [];\n for (let i = 1; i <= maxAttempts; i++) out.push(2 ** i * 1000);\n return out;\n}\n\n/** Decide the four steps for one domain from its desired config and live state. */\nexport function planDomain(setup: DomainSetup, state: DomainState): DomainPlan {\n const reminders: string[] = [];\n if (setup.fullUserGroup)\n reminders.push(\n `add ${setup.fullUserGroup} as a Full User in Search Console — no API exists for this, do it in the UI`,\n );\n\n const txt: StepPlan = state.txtPresent\n ? { action: 'skip', detail: 'apex TXT already present' }\n : { action: 'create', detail: 'create apex TXT verification record' };\n\n const verify: StepPlan = state.verified\n ? { action: 'skip', detail: 'ownership already verified' }\n : { action: 'create', detail: 'verify ownership (DNS_TXT)' };\n\n const property: StepPlan = state.propertyExists\n ? { action: 'skip', detail: 'property already exists' }\n : { action: 'create', detail: `add property ${siteUrlFor(setup.domain)}` };\n\n // Owners can only be read once verified; before that, treat every delegated\n // owner as still-to-add so --check reports the drift rather than hiding it.\n const desired = setup.delegatedOwners ?? [];\n const present = new Set(state.currentOwners.map((o) => o.toLowerCase()));\n const ownersToAdd = desired.filter((o) => !present.has(o.toLowerCase()));\n const owners: StepPlan =\n desired.length === 0\n ? { action: 'skip', detail: 'no delegated owners' }\n : ownersToAdd.length === 0\n ? { action: 'skip', detail: 'all delegated owners already present' }\n : {\n action: 'update',\n detail: `add ${ownersToAdd.length} owner(s): ${ownersToAdd.join(', ')}`,\n };\n\n return {\n domain: setup.domain,\n siteUrl: siteUrlFor(setup.domain),\n txt,\n verify,\n property,\n owners,\n ownersToAdd,\n reminders,\n };\n}\n\n/**\n * The owner set to PUT: everyone already there, plus everyone being added.\n *\n * `updateOwners` REPLACES the owner list, so this is the one computation standing\n * between a delegation and locking yourself out — pass a bare `ownersToAdd` and\n * the account that just verified the domain is removed from it. It belongs here\n * rather than at the call site for exactly that reason: it is a decision, it is\n * the dangerous one, and the executor is not allowed to make it.\n *\n * `current` comes FIRST so the API's own casing survives dedupe; matching is\n * case-insensitive, mirroring `planDomain`'s `present` check, because Google\n * echoes back addresses in whatever case the account uses and a case-sensitive\n * `Set` would re-add an owner who is already there.\n */\nexport function ownerUnion(current: string[], toAdd: string[]): string[] {\n const out: string[] = [];\n const seen = new Set<string>();\n for (const o of [...current, ...toAdd]) {\n const key = o.toLowerCase();\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(o);\n }\n return out;\n}\n\n/** Plan every domain. */\nexport function plan(config: OnboardingConfig, states: Map<string, DomainState>): OnboardingPlan {\n const notes: string[] = [];\n const domains = config.domains.map((setup) => {\n const state = states.get(setup.domain);\n if (!state)\n // Should not happen — the CLI observes every domain before planning — but a\n // missing observation must not silently read as \"nothing to do\".\n notes.push(`${setup.domain}: no observed state; treating everything as pending`);\n return planDomain(\n setup,\n state ?? { txtPresent: false, verified: false, currentOwners: [], propertyExists: false },\n );\n });\n return { domains, notes };\n}\n\n/** Any step on any domain is a mutation — i.e. the live state has drifted. */\nexport function hasDrift(p: OnboardingPlan): boolean {\n return p.domains.some(\n (d) =>\n d.txt.action !== 'skip' ||\n d.verify.action !== 'skip' ||\n d.property.action !== 'skip' ||\n d.owners.action !== 'skip',\n );\n}\n\n/** Render a plan as the block `--dry` and `--check` print. */\nexport function formatPlan(p: OnboardingPlan): string {\n const lines: string[] = [];\n const glyph = (s: StepPlan) => (s.action === 'skip' ? '·' : '+');\n for (const d of p.domains) {\n lines.push(d.domain);\n lines.push(` ${glyph(d.txt)} TXT ${d.txt.detail}`);\n lines.push(` ${glyph(d.verify)} verify ${d.verify.detail}`);\n lines.push(` ${glyph(d.property)} property ${d.property.detail}`);\n lines.push(` ${glyph(d.owners)} owners ${d.owners.detail}`);\n for (const r of d.reminders) lines.push(` ! ${r}`);\n }\n for (const n of p.notes) lines.push(`! ${n}`);\n return lines.join('\\n');\n}\n\n/** The outcome of one domain's run, for the summary table. */\nexport interface DomainResult {\n domain: string;\n txt: 'created' | 'present' | 'failed' | '—';\n verified: 'yes' | 'pending' | 'failed' | '—';\n property: 'added' | 'present' | 'failed' | '—';\n reminders: string[];\n}\n\n/** Render the end-of-run summary: one row per domain, plus any reminders. */\nexport function formatSummary(results: DomainResult[]): string {\n const headers = ['DOMAIN', 'TXT', 'VERIFIED', 'PROPERTY'];\n const rows = results.map((r) => [r.domain, r.txt, r.verified, r.property]);\n const reminders = results.flatMap((r) => r.reminders.map((m) => ` ! ${r.domain}: ${m}`));\n return table(headers, rows, reminders);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
//#region src/onboarding/types.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* The onboarding module's own option surface.
|
|
4
|
+
*
|
|
5
|
+
* Deliberately structural rather than `Config['site']['searchConsole']` imported
|
|
6
|
+
* from `@getvitops/generator`: the generator already depends on this package, so
|
|
7
|
+
* importing back would be a cycle. The vocabulary mirrors that block field for
|
|
8
|
+
* field, so the CLI's adapter is a flat map — the same arrangement, and for the
|
|
9
|
+
* same reason, as `IndexingConfig` beside it.
|
|
10
|
+
*
|
|
11
|
+
* Optional fields are written `?: T | undefined` throughout: `exactOptionalPropertyTypes`
|
|
12
|
+
* is on, and these types describe a *parsed JSON config* where an absent key and an
|
|
13
|
+
* explicit `undefined` are the same thing.
|
|
14
|
+
*/
|
|
15
|
+
/** One domain to onboard, as the config declares it. */
|
|
16
|
+
interface DomainSetup {
|
|
17
|
+
/** The domain, bare (`acme.ca`). Becomes the `sc-domain:` property and the DNS zone name. */
|
|
18
|
+
domain: string;
|
|
19
|
+
/**
|
|
20
|
+
* Emails added as verification owners on the Site Verification web resource.
|
|
21
|
+
* Additive: existing owners are never removed.
|
|
22
|
+
*/
|
|
23
|
+
delegatedOwners?: string[] | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* A Google Group to grant Full-User access in Search Console. Surfaced as a
|
|
26
|
+
* reminder only — Search Console has no user/permission API.
|
|
27
|
+
*/
|
|
28
|
+
fullUserGroup?: string | undefined;
|
|
29
|
+
}
|
|
30
|
+
/** Everything `plan()` needs, once the CLI has read the config and creds. */
|
|
31
|
+
interface OnboardingConfig {
|
|
32
|
+
/** The domains to onboard. Already filtered to `--domain` if that was passed. */
|
|
33
|
+
domains: DomainSetup[];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* One domain's observed live state, gathered by the executors before planning.
|
|
37
|
+
*
|
|
38
|
+
* `plan()` compares this against the desired `DomainSetup` to decide each step —
|
|
39
|
+
* the same shape the indexing planner takes its sitemap snapshot in, for the same
|
|
40
|
+
* reason: the decision is pure, the observation is not.
|
|
41
|
+
*/
|
|
42
|
+
interface DomainState {
|
|
43
|
+
/** The Cloudflare zone id for the domain, if one was found. */
|
|
44
|
+
zoneId?: string | undefined;
|
|
45
|
+
/** An apex TXT record already carrying the verification token exists. */
|
|
46
|
+
txtPresent: boolean;
|
|
47
|
+
/** The Site Verification web resource reports this domain as verified. */
|
|
48
|
+
verified: boolean;
|
|
49
|
+
/** Owners currently on the web resource (empty when not yet verified). */
|
|
50
|
+
currentOwners: string[];
|
|
51
|
+
/** A `sc-domain:` property already exists in Search Console. */
|
|
52
|
+
propertyExists: boolean;
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
//#region src/onboarding/plan.d.ts
|
|
56
|
+
/** A step's decision: do it, or skip it because it already holds. */
|
|
57
|
+
type StepAction = 'create' | 'update' | 'skip';
|
|
58
|
+
interface StepPlan {
|
|
59
|
+
action: StepAction;
|
|
60
|
+
/** Why it's a skip, or what the mutation will do. */
|
|
61
|
+
detail: string;
|
|
62
|
+
}
|
|
63
|
+
/** The four onboarding steps for one domain, decided against its live state. */
|
|
64
|
+
interface DomainPlan {
|
|
65
|
+
domain: string;
|
|
66
|
+
/** `sc-domain:` property identifier this domain maps to. */
|
|
67
|
+
siteUrl: string;
|
|
68
|
+
/** Ensure the apex TXT verification record. */
|
|
69
|
+
txt: StepPlan;
|
|
70
|
+
/** Verify ownership via the Site Verification API (DNS_TXT). */
|
|
71
|
+
verify: StepPlan;
|
|
72
|
+
/** Add the Search Console domain property. */
|
|
73
|
+
property: StepPlan;
|
|
74
|
+
/** Add delegated owners to the verified web resource. */
|
|
75
|
+
owners: StepPlan;
|
|
76
|
+
/** Owners not yet present that the run should add. */
|
|
77
|
+
ownersToAdd: string[];
|
|
78
|
+
/** Manual follow-ups (e.g. a Full-User group). */
|
|
79
|
+
reminders: string[];
|
|
80
|
+
}
|
|
81
|
+
interface OnboardingPlan {
|
|
82
|
+
domains: DomainPlan[];
|
|
83
|
+
/** Operator-facing warnings that span the whole run. */
|
|
84
|
+
notes: string[];
|
|
85
|
+
}
|
|
86
|
+
/** The `sc-domain:` property identifier for a bare domain. */
|
|
87
|
+
declare const siteUrlFor: (domain: string) => string;
|
|
88
|
+
/**
|
|
89
|
+
* Backoff ladder for the verification retry, in milliseconds.
|
|
90
|
+
*
|
|
91
|
+
* DNS_TXT verification fails until the record has propagated, which is a matter of
|
|
92
|
+
* seconds-to-minutes, not a real error — so the schedule is a *policy*, decided
|
|
93
|
+
* here and asserted in the tests, while the actual sleeping is the CLI's job.
|
|
94
|
+
* Capped at `maxAttempts`; a domain still unverified after the last attempt is
|
|
95
|
+
* reported PENDING, never failed.
|
|
96
|
+
*/
|
|
97
|
+
declare function backoffSchedule(maxAttempts?: number): number[];
|
|
98
|
+
/** Decide the four steps for one domain from its desired config and live state. */
|
|
99
|
+
declare function planDomain(setup: DomainSetup, state: DomainState): DomainPlan;
|
|
100
|
+
/**
|
|
101
|
+
* The owner set to PUT: everyone already there, plus everyone being added.
|
|
102
|
+
*
|
|
103
|
+
* `updateOwners` REPLACES the owner list, so this is the one computation standing
|
|
104
|
+
* between a delegation and locking yourself out — pass a bare `ownersToAdd` and
|
|
105
|
+
* the account that just verified the domain is removed from it. It belongs here
|
|
106
|
+
* rather than at the call site for exactly that reason: it is a decision, it is
|
|
107
|
+
* the dangerous one, and the executor is not allowed to make it.
|
|
108
|
+
*
|
|
109
|
+
* `current` comes FIRST so the API's own casing survives dedupe; matching is
|
|
110
|
+
* case-insensitive, mirroring `planDomain`'s `present` check, because Google
|
|
111
|
+
* echoes back addresses in whatever case the account uses and a case-sensitive
|
|
112
|
+
* `Set` would re-add an owner who is already there.
|
|
113
|
+
*/
|
|
114
|
+
declare function ownerUnion(current: string[], toAdd: string[]): string[];
|
|
115
|
+
/** Plan every domain. */
|
|
116
|
+
declare function plan(config: OnboardingConfig, states: Map<string, DomainState>): OnboardingPlan;
|
|
117
|
+
/** Any step on any domain is a mutation — i.e. the live state has drifted. */
|
|
118
|
+
declare function hasDrift(p: OnboardingPlan): boolean;
|
|
119
|
+
/** Render a plan as the block `--dry` and `--check` print. */
|
|
120
|
+
declare function formatPlan(p: OnboardingPlan): string;
|
|
121
|
+
/** The outcome of one domain's run, for the summary table. */
|
|
122
|
+
interface DomainResult {
|
|
123
|
+
domain: string;
|
|
124
|
+
txt: 'created' | 'present' | 'failed' | '—';
|
|
125
|
+
verified: 'yes' | 'pending' | 'failed' | '—';
|
|
126
|
+
property: 'added' | 'present' | 'failed' | '—';
|
|
127
|
+
reminders: string[];
|
|
128
|
+
}
|
|
129
|
+
/** Render the end-of-run summary: one row per domain, plus any reminders. */
|
|
130
|
+
declare function formatSummary(results: DomainResult[]): string;
|
|
131
|
+
//#endregion
|
|
132
|
+
export { StepPlan as a, formatSummary as c, plan as d, planDomain as f, OnboardingConfig as g, DomainState as h, StepAction as i, hasDrift as l, DomainSetup as m, DomainResult as n, backoffSchedule as o, siteUrlFor as p, OnboardingPlan as r, formatPlan as s, DomainPlan as t, ownerUnion as u };
|
|
133
|
+
//# sourceMappingURL=plan-Hq8Pb0Uw.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-Hq8Pb0Uw.d.mts","names":[],"sources":["../src/onboarding/types.ts","../src/onboarding/plan.ts"],"mappings":";;;;;;;;;;;;;;;UAeiB;;EAEf;;;;;EAKA;;;;;EAKA;;;UAIe;;EAEf,SAAS;;;;;;;;;UAiBM;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;;;;;KC3CU;UAEK;EACf,QAAQ;;EAER;;;UAIe;EACf;;EAEA;;EAEA,KAAK;;EAEL,QAAQ;;EAER,UAAU;;EAEV,QAAQ;;EAER;;EAEA;;UAGe;EACf,SAAS;;EAET;;;cAIW,aAAc;;;;;;;;;;iBAWX,gBAAgB;;iBAOhB,WAAW,OAAO,aAAa,OAAO,cAAc;;;;;;;;;;;;;;;iBA4DpD,WAAW,mBAAmB;;iBAa9B,KAAK,QAAQ,kBAAkB,QAAQ,YAAY,eAAe;;iBAiBlE,SAAS,GAAG;;iBAWZ,WAAW,GAAG;;UAgBb;EACf;EACA;EACA;EACA;EACA;;;iBAIc,cAAc,SAAS"}
|
package/dist/reviews/index.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { a as SCOPES, c as googleHeaders, i as GoogleOAuth, n as GoogleAuthLike, r as GoogleCredential, s as googleAccessToken, t as GoogleAuth } from "../token-
|
|
2
|
-
import { n as adcQuotaProject, r as parseAdcUser, t as adcCredentialsPath } from "../adc-
|
|
3
|
-
|
|
1
|
+
import { a as SCOPES, c as googleHeaders, i as GoogleOAuth, n as GoogleAuthLike, r as GoogleCredential, s as googleAccessToken, t as GoogleAuth } from "../token-DmmoQ7um.mjs";
|
|
2
|
+
import { n as adcQuotaProject, r as parseAdcUser, t as adcCredentialsPath } from "../adc-BoEoogyo.mjs";
|
|
4
3
|
//#region src/reviews/types.d.ts
|
|
5
4
|
/**
|
|
6
5
|
* The reviews module's own option surface.
|
|
@@ -91,9 +90,9 @@ interface PlanInput {
|
|
|
91
90
|
hasCredential: boolean;
|
|
92
91
|
}
|
|
93
92
|
/** Decide which locations to fetch, and why any are skipped. */
|
|
94
|
-
declare function plan(input: PlanInput): ReviewsPlan;
|
|
93
|
+
export declare function plan(input: PlanInput): ReviewsPlan;
|
|
95
94
|
/** Render a plan as the human-readable block `--dry` prints. */
|
|
96
|
-
declare function formatPlan(p: ReviewsPlan): string;
|
|
95
|
+
export declare function formatPlan(p: ReviewsPlan): string;
|
|
97
96
|
/**
|
|
98
97
|
* Filter and order one location's reviews for display.
|
|
99
98
|
*
|
|
@@ -103,7 +102,7 @@ declare function formatPlan(p: ReviewsPlan): string;
|
|
|
103
102
|
* is a design choice a config field should not have to spell out every time),
|
|
104
103
|
* sorted, then capped by `limit`.
|
|
105
104
|
*/
|
|
106
|
-
declare function selectReviews(reviews: Review[], config: ReviewLocationConfig): Review[];
|
|
105
|
+
export declare function selectReviews(reviews: Review[], config: ReviewLocationConfig): Review[];
|
|
107
106
|
/**
|
|
108
107
|
* Merge a fresh fetch into the existing cache.
|
|
109
108
|
*
|
|
@@ -112,11 +111,11 @@ declare function selectReviews(reviews: Review[], config: ReviewLocationConfig):
|
|
|
112
111
|
* failure (one location's fetch errors) non-destructive — `cmdReviews` merges
|
|
113
112
|
* only the locations that succeeded and leaves the rest of the cache alone.
|
|
114
113
|
*/
|
|
115
|
-
declare function mergeCache(existing: ReviewCache | undefined, fetched: Record<string, LocationReviews>): ReviewCache;
|
|
114
|
+
export declare function mergeCache(existing: ReviewCache | undefined, fetched: Record<string, LocationReviews>): ReviewCache;
|
|
116
115
|
//#endregion
|
|
117
116
|
//#region src/reviews/cache.d.ts
|
|
118
117
|
/** Default location, relative to the consumer's project root. */
|
|
119
|
-
declare const REVIEWS_CACHE_PATH = ".vitops/reviews.json";
|
|
118
|
+
export declare const REVIEWS_CACHE_PATH = ".vitops/reviews.json";
|
|
120
119
|
/**
|
|
121
120
|
* Read the cache, or `undefined` when there isn't a usable one.
|
|
122
121
|
*
|
|
@@ -125,11 +124,11 @@ declare const REVIEWS_CACHE_PATH = ".vitops/reviews.json";
|
|
|
125
124
|
* from "this business genuinely has no reviews" and silently ship an empty
|
|
126
125
|
* carousel.
|
|
127
126
|
*/
|
|
128
|
-
declare function readCache(path: string): ReviewCache | undefined;
|
|
127
|
+
export declare function readCache(path: string): ReviewCache | undefined;
|
|
129
128
|
/** Build a cache with its keys and each location's reviews in a stable order. */
|
|
130
|
-
declare function toCache(locations: Record<string, LocationReviews>): ReviewCache;
|
|
129
|
+
export declare function toCache(locations: Record<string, LocationReviews>): ReviewCache;
|
|
131
130
|
/** Write the cache, creating its directory. */
|
|
132
|
-
declare function writeCache(path: string, cache: ReviewCache): void;
|
|
131
|
+
export declare function writeCache(path: string, cache: ReviewCache): void;
|
|
133
132
|
//#endregion
|
|
134
133
|
//#region src/reviews/gbp.d.ts
|
|
135
134
|
/** One page (or, having paginated, the whole set) of a location's reviews. */
|
|
@@ -148,7 +147,7 @@ interface FetchReviewsResult {
|
|
|
148
147
|
* several locations can fetch what it can and report the rest, the same contract
|
|
149
148
|
* `../indexing/gsc.ts`'s `inspectUrl` keeps.
|
|
150
149
|
*/
|
|
151
|
-
declare function fetchReviews(auth: GoogleAuthLike, accountId: string, locationId: string, fetchImpl?: typeof fetch): Promise<FetchReviewsResult>;
|
|
150
|
+
export declare function fetchReviews(auth: GoogleAuthLike, accountId: string, locationId: string, fetchImpl?: typeof fetch): Promise<FetchReviewsResult>;
|
|
152
151
|
//#endregion
|
|
153
|
-
export { type FetchReviewsResult, type GoogleAuth, type GoogleAuthLike, type GoogleCredential, type GoogleOAuth, type LocationPlan, type LocationReviews, type PlanInput,
|
|
152
|
+
export { type FetchReviewsResult, type GoogleAuth, type GoogleAuthLike, type GoogleCredential, type GoogleOAuth, type LocationPlan, type LocationReviews, type PlanInput, type Review, type ReviewCache, type ReviewLocationConfig, type ReviewsConfig, type ReviewsPlan, SCOPES, adcCredentialsPath, adcQuotaProject, googleAccessToken, googleHeaders, parseAdcUser };
|
|
154
153
|
//# sourceMappingURL=index.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/reviews/types.ts","../../src/reviews/plan.ts","../../src/reviews/cache.ts","../../src/reviews/gbp.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/reviews/types.ts","../../src/reviews/plan.ts","../../src/reviews/cache.ts","../../src/reviews/gbp.ts"],"mappings":";;;;;;;;;;;;UAgBiB;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;;UAIe;;EAEf;;EAEA,WAAW,eAAe;;;UAIX;EACf;;EAEA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;IAAU;IAAc;;;EAExB;;;UAIe;EACf;EACA;EACA;EACA;EACA;EACA,SAAS;;;UAIM;EACf;EACA,WAAW,eAAe;;;;;UClDX;EACf;EACA;EACA;;EAEA;;UAGe;;EAEf;EACA,WAAW;EACX;;UAGe;EACf,QAAQ;;EAER,gBAAgB;;EAEhB;;EAEA;;;wBAIc,KAAK,OAAO,YAAY;;wBAuDxB,WAAW,GAAG;;;;;;;;;;wBAmBd,cAAc,SAAS,UAAU,QAAQ,uBAAuB;;;;;;;;;wBA2BhE,WACd,UAAU,yBACV,SAAS,eAAe,mBACvB;;;;qBCvIU;;;;;;;;;wBAUG,UAAU,eAAe;;wBAKzB,QAAQ,WAAW,eAAe,mBAAmB;;wBAarD,WAAW,cAAc,OAAO;;;;UCoB/B;EACf;EACA,SAAS;EACT;EACA;EACA;EACA;;;;;;;;;wBAUoB,aACpB,MAAM,gBACN,mBACA,oBACA,mBAAkB,QACjB,QAAQ"}
|
package/dist/schema/index.d.mts
CHANGED
|
@@ -20,7 +20,7 @@ interface ArticleGraphOptions {
|
|
|
20
20
|
keywords?: string[];
|
|
21
21
|
}
|
|
22
22
|
/** Build a schema.org Article JSON-LD graph. */
|
|
23
|
-
declare function articleGraph(options: ArticleGraphOptions): Record<string, unknown>;
|
|
23
|
+
export declare function articleGraph(options: ArticleGraphOptions): Record<string, unknown>;
|
|
24
24
|
//#endregion
|
|
25
25
|
//#region src/schema/breadcrumb.d.ts
|
|
26
26
|
interface BreadcrumbItem {
|
|
@@ -31,7 +31,7 @@ interface BreadcrumbGraphOptions {
|
|
|
31
31
|
items: BreadcrumbItem[];
|
|
32
32
|
}
|
|
33
33
|
/** Build a schema.org BreadcrumbList JSON-LD graph. */
|
|
34
|
-
declare function breadcrumbGraph(options: BreadcrumbGraphOptions): Record<string, unknown>;
|
|
34
|
+
export declare function breadcrumbGraph(options: BreadcrumbGraphOptions): Record<string, unknown>;
|
|
35
35
|
//#endregion
|
|
36
36
|
//#region src/schema/faq.d.ts
|
|
37
37
|
interface FAQItem {
|
|
@@ -47,7 +47,7 @@ interface FAQGraphOptions {
|
|
|
47
47
|
* NOTE: Google recommends FAQ markup only for authoritative government
|
|
48
48
|
* and health sites. For other sites, consider using QAPage schema instead.
|
|
49
49
|
*/
|
|
50
|
-
declare function faqGraph(options: FAQGraphOptions): Record<string, unknown>;
|
|
50
|
+
export declare function faqGraph(options: FAQGraphOptions): Record<string, unknown>;
|
|
51
51
|
//#endregion
|
|
52
52
|
//#region src/schema/itemList.d.ts
|
|
53
53
|
type ItemListEntryType = 'Article' | 'Recipe' | 'Movie' | 'Course' | 'Restaurant' | 'Product' | (string & {});
|
|
@@ -69,7 +69,7 @@ interface ItemListGraphOptions {
|
|
|
69
69
|
name?: string;
|
|
70
70
|
}
|
|
71
71
|
/** Build a schema.org ItemList JSON-LD graph (e.g. for a carousel rich result). */
|
|
72
|
-
declare function itemListGraph(options: ItemListGraphOptions): Record<string, unknown>;
|
|
72
|
+
export declare function itemListGraph(options: ItemListGraphOptions): Record<string, unknown>;
|
|
73
73
|
//#endregion
|
|
74
74
|
//#region src/schema/localBusiness.d.ts
|
|
75
75
|
interface OpeningHoursSpecification {
|
|
@@ -136,7 +136,7 @@ interface LocalBusinessGraphOptions {
|
|
|
136
136
|
knowsLanguage?: string[];
|
|
137
137
|
}
|
|
138
138
|
/** Build a schema.org LocalBusiness (or subtype) JSON-LD graph. */
|
|
139
|
-
declare function localBusinessGraph(options: LocalBusinessGraphOptions): Record<string, unknown>;
|
|
139
|
+
export declare function localBusinessGraph(options: LocalBusinessGraphOptions): Record<string, unknown>;
|
|
140
140
|
//#endregion
|
|
141
141
|
//#region src/schema/organization.d.ts
|
|
142
142
|
interface OrganizationGraphOptions {
|
|
@@ -185,7 +185,7 @@ interface OrganizationGraphOptions {
|
|
|
185
185
|
}[];
|
|
186
186
|
}
|
|
187
187
|
/** Build a schema.org Organization JSON-LD graph. */
|
|
188
|
-
declare function organizationGraph(options: OrganizationGraphOptions): Record<string, unknown>;
|
|
188
|
+
export declare function organizationGraph(options: OrganizationGraphOptions): Record<string, unknown>;
|
|
189
189
|
//#endregion
|
|
190
|
-
export {
|
|
190
|
+
export type { ArticleAuthor, ArticleGraphOptions, BreadcrumbGraphOptions, BreadcrumbItem, FAQGraphOptions, FAQItem, ItemListEntry, ItemListEntryType, ItemListGraphOptions, LocalBusinessGraphOptions, OpeningHoursSpecification, OrganizationGraphOptions, SpecialHoursSpecification };
|
|
191
191
|
//# sourceMappingURL=index.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/schema/article.ts","../../src/schema/breadcrumb.ts","../../src/schema/faq.ts","../../src/schema/itemList.ts","../../src/schema/localBusiness.ts","../../src/schema/organization.ts"],"mappings":";UAAiB
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/schema/article.ts","../../src/schema/breadcrumb.ts","../../src/schema/faq.ts","../../src/schema/itemList.ts","../../src/schema/localBusiness.ts","../../src/schema/organization.ts"],"mappings":";UAAiB;EACf;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA,QAAQ,gBAAgB;EACxB;IACE;IACA;;EAEF;EACA;EACA;EACA;;;wBAIc,aAAa,SAAS,sBAAsB;;;UCvB3C;EACf;EACA;;UAGe;EACf,OAAO;;;wBAIO,gBAAgB,SAAS,yBAAyB;;;UCVjD;EACf;EACA;;UAGe;EACf,OAAO;;;;;;;;wBASO,SAAS,SAAS,kBAAkB;;;KCfxC;UAWK;EACf,MAAM;EACN;;;;;;EAMA;EACA;EACA;;UAGe;EACf,OAAO;;EAEP;;;wBAIc,cAAc,SAAS,uBAAuB;;;UC/B7C;EACf;EACA;EACA;;;;;;;;UASe;EACf;EACA;EACA;EACA;;UAGe;;EAEf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;IACE;IACA;IACA;IACA;IACA;;EAEF;IACE;IACA;;EAEF,4BAA4B;EAC5B,mCAAmC;EACnC;IACE;IACA;IACA;IACA;IACA;;EAEF;IACE;IACA;IACA;IACA;MACE;MACA;MACA;;;EAGJ;EACA;EACA;EACA;EACA;;;wBAIc,mBAAmB,SAAS,4BAA4B;;;UCnEvD;EACf;EACA;EACA;EACA;EACA;EACA;EACA;IACE;IACA;IACA;IACA;IACA;;EAEF;EACA;EACA;EACA;IAA+B;IAAkB;;EACjD;IACE;IACA;;EAEF;IACE;IACA;;EAEF;IACE;IACA;IACA;IACA;IACA;IACA;;EAEF;EACA;EACA;EACA;IACE;IACA;;;;wBAKY,kBAAkB,SAAS,2BAA2B"}
|
|
@@ -42,7 +42,7 @@ interface TurnstileVerifyResult {
|
|
|
42
42
|
* failed verification is not this module's business to act on; the caller
|
|
43
43
|
* (`createConversionRoute`) decides what a failure means for the request.
|
|
44
44
|
*/
|
|
45
|
-
declare function verifyTurnstileToken(token: string, secretKey: string, remoteIp?: string, fetchImpl?: typeof fetch): Promise<TurnstileVerifyResult>;
|
|
45
|
+
export declare function verifyTurnstileToken(token: string, secretKey: string, remoteIp?: string, fetchImpl?: typeof fetch): Promise<TurnstileVerifyResult>;
|
|
46
46
|
//#endregion
|
|
47
|
-
export {
|
|
47
|
+
export type { TurnstileVerifyResult };
|
|
48
48
|
//# sourceMappingURL=index.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/security/turnstile.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/security/turnstile.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA+BiB;EACf;;EAEA;;;;;;;;;;;;wBAaoB,qBACpB,eACA,mBACA,mBACA,mBAAkB,QACjB,QAAQ"}
|
|
@@ -65,10 +65,13 @@ type GoogleAuthLike = string | GoogleAuth;
|
|
|
65
65
|
declare function googleHeaders(auth: GoogleAuthLike, extra?: Record<string, string>): Record<string, string>;
|
|
66
66
|
/** Scopes, named once so a caller never spells one out. */
|
|
67
67
|
declare const SCOPES: {
|
|
68
|
-
/** Search Console (`sitemaps.submit`, `urlInspection`, `sites`). */
|
|
69
|
-
readonly
|
|
68
|
+
/** Search Console (`sitemaps.submit`, `urlInspection`, `sites`). */
|
|
69
|
+
readonly webmasters: "https://www.googleapis.com/auth/webmasters";
|
|
70
|
+
/** Site Verification API. */
|
|
71
|
+
readonly siteVerification: "https://www.googleapis.com/auth/siteverification";
|
|
72
|
+
/** Business Profile (reviews). The GCP project must be allowlisted by Google. */
|
|
70
73
|
readonly businessProfile: "https://www.googleapis.com/auth/business.manage";
|
|
71
74
|
};
|
|
72
75
|
//#endregion
|
|
73
76
|
export { SCOPES as a, googleHeaders as c, GoogleOAuth as i, GoogleAuthLike as n, ServiceAccount as o, GoogleCredential as r, googleAccessToken as s, GoogleAuth as t };
|
|
74
|
-
//# sourceMappingURL=token-
|
|
77
|
+
//# sourceMappingURL=token-DmmoQ7um.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-DmmoQ7um.d.mts","names":[],"sources":["../src/google/token.ts"],"mappings":";;UAkCiB;EACf;EACA;;;UAIe;EACf;EACA;EACA;;;;;;;;;;KAWU;EACN;EAAyB,SAAS;EAAgB;;EAClD;EAAe,OAAO;;;;;;;;;;;iBA8CZ,kBACd,YAAY,kBACZ,mBAAkB,OAClB,eACC;;;;;;;;;;;;;;UA6Bc;EACf;EACA;;;;;;;;;KAUU,0BAA0B;;iBAGtB,cACd,MAAM,gBACN,QAAQ,yBACP;;cA2BU"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { i as TrackingData, n as TrackingCategory, r as TrackingConfig, t as ConversionEvent } from "../types-
|
|
2
|
-
|
|
1
|
+
import { i as TrackingData, n as TrackingCategory, r as TrackingConfig, t as ConversionEvent } from "../types-7ELci8RQ.mjs";
|
|
3
2
|
//#region src/tracking/params.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* The ad-platform vocabulary — the one place that says which URL parameters mean
|
|
@@ -23,12 +22,12 @@ import { i as TrackingData, n as TrackingCategory, r as TrackingConfig, t as Con
|
|
|
23
22
|
* unattributed — silently, since an unattributed conversion looks exactly like an
|
|
24
23
|
* organic one. `li_fat_id` and `epik` were missing for precisely that reason.
|
|
25
24
|
*/
|
|
26
|
-
declare const PLATFORM_PARAMS: Readonly<Record<string, string>>;
|
|
25
|
+
export declare const PLATFORM_PARAMS: Readonly<Record<string, string>>;
|
|
27
26
|
/** Just the parameter names, in the same precedence order. */
|
|
28
|
-
declare const CLICK_ID_PARAMS: readonly string[];
|
|
29
|
-
declare const UTM_PARAMS: readonly ["utm_source", "utm_medium", "utm_campaign", "utm_content", "utm_term"];
|
|
27
|
+
export declare const CLICK_ID_PARAMS: readonly string[];
|
|
28
|
+
export declare const UTM_PARAMS: readonly ["utm_source", "utm_medium", "utm_campaign", "utm_content", "utm_term"];
|
|
30
29
|
/** Everything the capture script pulls off the landing URL. */
|
|
31
|
-
declare const TRACKED_PARAMS: readonly string[];
|
|
30
|
+
export declare const TRACKED_PARAMS: readonly string[];
|
|
32
31
|
/**
|
|
33
32
|
* The attribution cookie.
|
|
34
33
|
*
|
|
@@ -36,15 +35,15 @@ declare const TRACKED_PARAMS: readonly string[];
|
|
|
36
35
|
* never sent anywhere. It is still a persistent identifier, which is why writing
|
|
37
36
|
* it waits on consent.
|
|
38
37
|
*/
|
|
39
|
-
declare const TRACKING_COOKIE = "_ac";
|
|
38
|
+
export declare const TRACKING_COOKIE = "_ac";
|
|
40
39
|
/** 90 days — an ad click and the conversion it produces are rarely further apart. */
|
|
41
|
-
declare const TRACKING_COOKIE_DAYS = 90;
|
|
40
|
+
export declare const TRACKING_COOKIE_DAYS = 90;
|
|
42
41
|
/** The A/B variant cookie, assigned by the router when a site runs experiments. */
|
|
43
|
-
declare const AB_COOKIE = "_ab";
|
|
42
|
+
export declare const AB_COOKIE = "_ab";
|
|
44
43
|
//#endregion
|
|
45
44
|
//#region src/tracking/cookie.d.ts
|
|
46
45
|
/** Read one cookie out of a `document.cookie`-shaped string. */
|
|
47
|
-
declare function readCookie(cookieString: string | null | undefined, name: string): string | null;
|
|
46
|
+
export declare function readCookie(cookieString: string | null | undefined, name: string): string | null;
|
|
48
47
|
/**
|
|
49
48
|
* Cookie header → attribution, or `null`.
|
|
50
49
|
*
|
|
@@ -53,9 +52,9 @@ declare function readCookie(cookieString: string | null | undefined, name: strin
|
|
|
53
52
|
* fields happened to survive, which is worse than reporting it unattributed:
|
|
54
53
|
* "we don't know" is actionable, a wrong campaign is not.
|
|
55
54
|
*/
|
|
56
|
-
declare function parseTrackingCookie(cookieHeader: string | null | undefined): TrackingData | null;
|
|
55
|
+
export declare function parseTrackingCookie(cookieHeader: string | null | undefined): TrackingData | null;
|
|
57
56
|
/** Attribution → cookie value (not the full `Set-Cookie` — see `cookieAttributes`). */
|
|
58
|
-
declare function serializeTrackingCookie(data: TrackingData): string;
|
|
57
|
+
export declare function serializeTrackingCookie(data: TrackingData): string;
|
|
59
58
|
/**
|
|
60
59
|
* Attributes for the attribution cookie.
|
|
61
60
|
*
|
|
@@ -64,7 +63,7 @@ declare function serializeTrackingCookie(data: TrackingData): string;
|
|
|
64
63
|
* cross-site navigation — so a returning click would read as a fresh one. No
|
|
65
64
|
* `HttpOnly`, because the capture script has to write it from the page.
|
|
66
65
|
*/
|
|
67
|
-
declare function cookieAttributes(now: number, secure: boolean): string;
|
|
66
|
+
export declare function cookieAttributes(now: number, secure: boolean): string;
|
|
68
67
|
/**
|
|
69
68
|
* Fold a fresh capture into whatever was already stored.
|
|
70
69
|
*
|
|
@@ -73,7 +72,7 @@ declare function cookieAttributes(now: number, secure: boolean): string;
|
|
|
73
72
|
* Taking the latest would restart the window on every visit and make the cookie
|
|
74
73
|
* outlive the click it represents.
|
|
75
74
|
*/
|
|
76
|
-
declare function mergeTracking(existing: TrackingData | null, captured: TrackingData, now: number): TrackingData;
|
|
75
|
+
export declare function mergeTracking(existing: TrackingData | null, captured: TrackingData, now: number): TrackingData;
|
|
77
76
|
//#endregion
|
|
78
77
|
//#region src/tracking/platform.d.ts
|
|
79
78
|
/**
|
|
@@ -83,12 +82,39 @@ declare function mergeTracking(existing: TrackingData | null, captured: Tracking
|
|
|
83
82
|
* a newsletter or a partner site is still attribution, just self-declared rather
|
|
84
83
|
* than platform-issued. Returns null when there is nothing to go on.
|
|
85
84
|
*/
|
|
86
|
-
declare function identifyPlatform(data: TrackingData): string | null;
|
|
85
|
+
export declare function identifyPlatform(data: TrackingData): string | null;
|
|
87
86
|
/** The click ID to quote, with the parameter it came from. */
|
|
88
|
-
declare function getPrimaryClickId(data: TrackingData): {
|
|
87
|
+
export declare function getPrimaryClickId(data: TrackingData): {
|
|
89
88
|
param: string;
|
|
90
89
|
value: string;
|
|
91
90
|
} | null;
|
|
92
91
|
//#endregion
|
|
93
|
-
|
|
92
|
+
//#region src/tracking/identity.d.ts
|
|
93
|
+
/**
|
|
94
|
+
* Pulling a submitter's identity out of a form's fields.
|
|
95
|
+
*
|
|
96
|
+
* Extracted from `notify/render.ts`'s `submitterName()`, which needed only the
|
|
97
|
+
* display name for a subject line. `crm/map.ts` needs the whole set — first
|
|
98
|
+
* name, last name, email, phone, company — to fill a CRM record, and a form's
|
|
99
|
+
* field names vary the same way `submitterName()` already accounted for
|
|
100
|
+
* (`name` vs `first_name`/`last_name` vs neither). Two independent cascades
|
|
101
|
+
* over the same handful of aliases is exactly the failure `render.ts`'s own
|
|
102
|
+
* comment records: a downstream site had five of six forms carrying
|
|
103
|
+
* `first_name`/`last_name`, and a cascade that only checked `name` read every
|
|
104
|
+
* one of them as "Unknown". Keep this the one place that knows the aliases;
|
|
105
|
+
* `submitterName()` and `crm/map.ts` both delegate to it.
|
|
106
|
+
*/
|
|
107
|
+
interface SubmitterIdentity {
|
|
108
|
+
firstName?: string | undefined;
|
|
109
|
+
lastName?: string | undefined;
|
|
110
|
+
/** The best available display name — a submitted full name, first + last
|
|
111
|
+
* joined, or the email address as a last resort. Never empty. */
|
|
112
|
+
fullName: string;
|
|
113
|
+
email?: string | undefined;
|
|
114
|
+
phone?: string | undefined;
|
|
115
|
+
company?: string | undefined;
|
|
116
|
+
}
|
|
117
|
+
export declare function identifySubmitter(formData: Record<string, string>): SubmitterIdentity;
|
|
118
|
+
//#endregion
|
|
119
|
+
export type { ConversionEvent, SubmitterIdentity, TrackingCategory, TrackingConfig, TrackingData };
|
|
94
120
|
//# sourceMappingURL=index.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/tracking/params.ts","../../src/tracking/cookie.ts","../../src/tracking/platform.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/tracking/params.ts","../../src/tracking/cookie.ts","../../src/tracking/platform.ts","../../src/tracking/identity.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;qBAuBa,iBAAiB,SAAS;;qBAc1B;qBAEA;;qBASA;;;;;;;;qBASA;;qBAGA;;qBAGA;;;;wBChDG,WAAW,yCAAyC;;;;;;;;;wBAiBpD,oBAAoB,0CAA0C;;wBAa9D,wBAAwB,MAAM;;;;;;;;;wBAe9B,iBAAiB,aAAa;;;;;;;;;wBAa9B,cACd,UAAU,qBACV,UAAU,cACV,cACC;;;;;;;;;;wBC3Da,iBAAiB,MAAM;;wBASvB,kBAAkB,MAAM;EAAiB;EAAe;;;;;;;;;;;;;;;;;;UCZvD;EACf;EACA;;;EAGA;EACA;EACA;EACA;;wBAWc,kBAAkB,UAAU,yBAAyB"}
|
package/dist/tracking/index.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { t as identifySubmitter } from "../identity-BoRddTx3.mjs";
|
|
1
2
|
import { a as PLATFORM_PARAMS, c as TRACKING_COOKIE_DAYS, i as CLICK_ID_PARAMS, l as UTM_PARAMS, n as identifyPlatform, o as TRACKED_PARAMS, r as AB_COOKIE, s as TRACKING_COOKIE, t as getPrimaryClickId } from "../platform-0nlOIy8h.mjs";
|
|
2
3
|
|
|
3
4
|
//#region src/tracking/cookie.ts
|
|
@@ -73,5 +74,5 @@ function mergeTracking(existing, captured, now) {
|
|
|
73
74
|
}
|
|
74
75
|
|
|
75
76
|
//#endregion
|
|
76
|
-
export { AB_COOKIE, CLICK_ID_PARAMS, PLATFORM_PARAMS, TRACKED_PARAMS, TRACKING_COOKIE, TRACKING_COOKIE_DAYS, UTM_PARAMS, cookieAttributes, getPrimaryClickId, identifyPlatform, mergeTracking, parseTrackingCookie, readCookie, serializeTrackingCookie };
|
|
77
|
+
export { AB_COOKIE, CLICK_ID_PARAMS, PLATFORM_PARAMS, TRACKED_PARAMS, TRACKING_COOKIE, TRACKING_COOKIE_DAYS, UTM_PARAMS, cookieAttributes, getPrimaryClickId, identifyPlatform, identifySubmitter, mergeTracking, parseTrackingCookie, readCookie, serializeTrackingCookie };
|
|
77
78
|
//# sourceMappingURL=index.mjs.map
|