@drip-apex/apex-cli 0.14.1 → 0.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +170 -85
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -7325,7 +7325,7 @@ async function checkForUpdate(current) {
|
|
|
7325
7325
|
// package.json
|
|
7326
7326
|
var package_default = {
|
|
7327
7327
|
name: "@drip-apex/apex-cli",
|
|
7328
|
-
version: "0.14.
|
|
7328
|
+
version: "0.14.2",
|
|
7329
7329
|
license: "MIT",
|
|
7330
7330
|
description: "Apex CLI for managing experiments, approved roadmap ideas, and draft workspaces.",
|
|
7331
7331
|
private: false,
|
|
@@ -9549,10 +9549,10 @@ var evidenceKinds = [
|
|
|
9549
9549
|
|
|
9550
9550
|
// src/lib/experiment-handover.ts
|
|
9551
9551
|
function summarizeHandoverQa(value) {
|
|
9552
|
-
const
|
|
9553
|
-
const qa3 =
|
|
9554
|
-
const run3 =
|
|
9555
|
-
const summary =
|
|
9552
|
+
const record4 = (value2) => value2 !== null && typeof value2 === "object" && !Array.isArray(value2) ? value2 : {};
|
|
9553
|
+
const qa3 = record4(value);
|
|
9554
|
+
const run3 = record4(qa3.latestRun);
|
|
9555
|
+
const summary = record4(run3.summary);
|
|
9556
9556
|
const count2 = (value2) => typeof value2 === "number" && Number.isInteger(value2) && value2 >= 0 ? value2 : null;
|
|
9557
9557
|
let requiredDone = count2(summary.completedRequired);
|
|
9558
9558
|
let requiredTotal = count2(summary.required);
|
|
@@ -9627,12 +9627,6 @@ function deviceLabel(targeting) {
|
|
|
9627
9627
|
return void 0;
|
|
9628
9628
|
}
|
|
9629
9629
|
|
|
9630
|
-
// src/lib/test-key.ts
|
|
9631
|
-
var TEST_KEY_RE = /^([A-Z0-9]{2,8})-(\d+)$/;
|
|
9632
|
-
function isTestKeyReference(value) {
|
|
9633
|
-
return value === value.toUpperCase() && TEST_KEY_RE.test(value.toUpperCase());
|
|
9634
|
-
}
|
|
9635
|
-
|
|
9636
9630
|
// src/lib/effective-page-targeting.ts
|
|
9637
9631
|
var ALL_PAGES_LABEL = "All pages";
|
|
9638
9632
|
var CHECKOUT_LABEL = "Checkout";
|
|
@@ -9719,6 +9713,99 @@ function classifyIdeaReference(reference) {
|
|
|
9719
9713
|
return { kind: "invalid", value: trimmed };
|
|
9720
9714
|
}
|
|
9721
9715
|
|
|
9716
|
+
// ../api-client/src/experiments.ts
|
|
9717
|
+
var ID_REFERENCE = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|[1-9][0-9]{9})$/i;
|
|
9718
|
+
function isExperimentTestKey(value) {
|
|
9719
|
+
return /^([A-Z0-9]{2,8})-(\d+)$/.test(value);
|
|
9720
|
+
}
|
|
9721
|
+
function record(value) {
|
|
9722
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
9723
|
+
}
|
|
9724
|
+
async function resolveExperimentReference(request2, idOrSlug, variationRef) {
|
|
9725
|
+
const explicitSlug = idOrSlug.startsWith("slug:");
|
|
9726
|
+
const reference = explicitSlug ? idOrSlug.slice(5) : idOrSlug;
|
|
9727
|
+
const idShaped = !explicitSlug && ID_REFERENCE.test(reference);
|
|
9728
|
+
const keyShaped = !explicitSlug && isExperimentTestKey(reference);
|
|
9729
|
+
const slugPath = `/api/v1/experiments/by-slug/${encodeURIComponent(reference)}`;
|
|
9730
|
+
let res = await request2("GET", idShaped || keyShaped ? `/api/v1/experiments/${encodeURIComponent(reference)}` : slugPath);
|
|
9731
|
+
if (!res.ok && res.status === 404 && idShaped) res = await request2("GET", slugPath);
|
|
9732
|
+
if (!res.ok) return { ok: false, error: res.error ?? "Experiment not found", status: res.status, response: res };
|
|
9733
|
+
const experiment = record(res.data);
|
|
9734
|
+
if (typeof experiment.id !== "string") return { ok: false, error: "Experiment has no id" };
|
|
9735
|
+
const variations = Array.isArray(experiment.variations) ? experiment.variations.map(record) : [];
|
|
9736
|
+
if (variationRef === void 0) return { ok: true, experimentId: experiment.id, variations, experiment };
|
|
9737
|
+
const available = variations.map((v) => String(v.slug ?? v.name)).join(", ") || "none";
|
|
9738
|
+
const byIdentity = variations.filter((v) => v.id === variationRef || v.public_id === variationRef || v.slug === variationRef);
|
|
9739
|
+
const byName = variations.filter((v) => v.name === variationRef);
|
|
9740
|
+
const matches = byIdentity.length > 0 ? byIdentity : byName;
|
|
9741
|
+
if (matches.length > 1) return {
|
|
9742
|
+
ok: false,
|
|
9743
|
+
error: `Variation "${variationRef}" is ambiguous; use one of these slugs: ${matches.map((v) => String(v.slug)).join(", ")}`
|
|
9744
|
+
};
|
|
9745
|
+
const match2 = matches[0];
|
|
9746
|
+
if (typeof match2?.id !== "string") return { ok: false, error: `Variation "${variationRef}" not found. Available: ${available}` };
|
|
9747
|
+
return { ok: true, experimentId: experiment.id, variationId: match2.id, variations, experiment };
|
|
9748
|
+
}
|
|
9749
|
+
function summarizeResults(payload) {
|
|
9750
|
+
const data = record(payload);
|
|
9751
|
+
const experiment = record(data.experiment);
|
|
9752
|
+
const decision = record(data.decision);
|
|
9753
|
+
const outcome = record(data.effective_outcome);
|
|
9754
|
+
const commerce = record(data.commerce);
|
|
9755
|
+
const rawArms = Array.isArray(data.arms) ? data.arms.map(record) : [];
|
|
9756
|
+
const degradedFlags = {
|
|
9757
|
+
explicit: data.degraded === true,
|
|
9758
|
+
commerceUnavailable: commerce.unavailable === true,
|
|
9759
|
+
armMetricsMissing: rawArms.some((arm) => arm.primaryConversions == null || arm.primaryRate == null)
|
|
9760
|
+
};
|
|
9761
|
+
const missing = /* @__PURE__ */ new Set();
|
|
9762
|
+
if (degradedFlags.commerceUnavailable) missing.add("commerce orders");
|
|
9763
|
+
const controlRate = rawArms.find((arm) => arm.isControl === true)?.primaryRate;
|
|
9764
|
+
const treatmentCount = rawArms.filter((arm) => arm.isControl !== true).length;
|
|
9765
|
+
const arms = rawArms.map((arm) => {
|
|
9766
|
+
const judged = arm.isControl !== true && (decision.treatmentVariationId != null ? arm.variationId === decision.treatmentVariationId : treatmentCount === 1);
|
|
9767
|
+
let lift = null;
|
|
9768
|
+
let confidence = null;
|
|
9769
|
+
if (arm.isControl !== true) {
|
|
9770
|
+
if (judged) {
|
|
9771
|
+
lift = decision.lift;
|
|
9772
|
+
confidence = decision.judgedConfidence;
|
|
9773
|
+
} else if (typeof arm.primaryRate === "number" && typeof controlRate === "number" && controlRate > 0)
|
|
9774
|
+
lift = Math.round((arm.primaryRate / controlRate - 1) * 1e4) / 100;
|
|
9775
|
+
if (lift == null) missing.add("lift");
|
|
9776
|
+
if (judged && confidence == null) missing.add("confidence");
|
|
9777
|
+
}
|
|
9778
|
+
if (arm.visitors == null) missing.add("visitors");
|
|
9779
|
+
if (arm.primaryConversions == null) missing.add("conversions");
|
|
9780
|
+
if (arm.primaryRate == null) missing.add("conversion rate");
|
|
9781
|
+
return { ...arm, lift, confidence, judged };
|
|
9782
|
+
});
|
|
9783
|
+
const verdictWithheld = decision.state === "untrustworthy";
|
|
9784
|
+
return {
|
|
9785
|
+
experiment,
|
|
9786
|
+
runWindow: { startedAt: experiment.resultsWindowStartedAt ?? experiment.startedAt, endedAt: experiment.endedAt },
|
|
9787
|
+
primaryGoal: decision.primaryGoalName,
|
|
9788
|
+
totals: record(data.totals),
|
|
9789
|
+
decision,
|
|
9790
|
+
outcome,
|
|
9791
|
+
arms,
|
|
9792
|
+
judgedArm: arms.find((arm) => arm.judged)?.variationId,
|
|
9793
|
+
verdict: outcome.outcome ?? decision.state,
|
|
9794
|
+
verdictWithheld,
|
|
9795
|
+
statisticsState: (verdictWithheld ? decision.state : outcome.statisticsOutcome ?? decision.state) ?? "unknown",
|
|
9796
|
+
presentedOutcome: (verdictWithheld && outcome.provenance !== "manager_decided" ? decision.state : outcome.outcome ?? decision.state) ?? "unknown",
|
|
9797
|
+
degraded: Object.values(degradedFlags).some(Boolean),
|
|
9798
|
+
degradedFlags,
|
|
9799
|
+
missingMetrics: [...missing],
|
|
9800
|
+
warnings: Array.isArray(data.warnings) ? data.warnings.map((value) => ({
|
|
9801
|
+
message: record(value).message,
|
|
9802
|
+
value
|
|
9803
|
+
})) : [],
|
|
9804
|
+
metrics: Array.isArray(data.metrics) ? data.metrics.map(record) : [],
|
|
9805
|
+
resultsWeekdays: data.results_weekdays
|
|
9806
|
+
};
|
|
9807
|
+
}
|
|
9808
|
+
|
|
9722
9809
|
// ../api-client/src/experiment-create.ts
|
|
9723
9810
|
function deriveStoreUrl(patterns) {
|
|
9724
9811
|
for (const pattern of patterns) {
|
|
@@ -9984,14 +10071,9 @@ function formatRevenue(value, currency) {
|
|
|
9984
10071
|
}
|
|
9985
10072
|
}
|
|
9986
10073
|
function printExperimentResults(results2, currency) {
|
|
9987
|
-
const
|
|
9988
|
-
const
|
|
9989
|
-
const
|
|
9990
|
-
const effectiveOutcome = results2.effective_outcome ?? {};
|
|
9991
|
-
const outcomeProvenance = effectiveOutcome.provenance === "manager_decided" ? " (manager decided)" : "";
|
|
9992
|
-
const verdictWithheld = decision.state === "untrustworthy";
|
|
9993
|
-
const statisticsState = verdictWithheld ? decision.state : effectiveOutcome.statisticsOutcome ?? decision.state ?? "unknown";
|
|
9994
|
-
const presentedOutcome = verdictWithheld && effectiveOutcome.provenance !== "manager_decided" ? decision.state : effectiveOutcome.outcome ?? decision.state ?? "unknown";
|
|
10074
|
+
const summary = summarizeResults(results2);
|
|
10075
|
+
const { experiment, totals, decision, verdictWithheld, statisticsState, presentedOutcome } = summary;
|
|
10076
|
+
const outcomeProvenance = summary.outcome.provenance === "manager_decided" ? " (manager decided)" : "";
|
|
9995
10077
|
console.log();
|
|
9996
10078
|
console.log(source_default.bold(String(experiment.name ?? experiment.id ?? "Experiment results")));
|
|
9997
10079
|
console.log(` Status: ${statusBadge(String(experiment.status ?? "unknown"))}`);
|
|
@@ -9999,7 +10081,7 @@ function printExperimentResults(results2, currency) {
|
|
|
9999
10081
|
console.log(` Conversions: ${String(totals.primaryConversions ?? 0)}`);
|
|
10000
10082
|
console.log(` Revenue: ${formatRevenue(totals.revenue, currency)}`);
|
|
10001
10083
|
console.log(` Outcome: ${statisticsStateLabel(presentedOutcome)}${outcomeProvenance}`);
|
|
10002
|
-
const resultsWeekdays =
|
|
10084
|
+
const resultsWeekdays = summary.resultsWeekdays;
|
|
10003
10085
|
if (resultsWeekdays && Array.isArray(resultsWeekdays.days)) {
|
|
10004
10086
|
const labels = {
|
|
10005
10087
|
monday: "Mon",
|
|
@@ -10022,7 +10104,7 @@ function printExperimentResults(results2, currency) {
|
|
|
10022
10104
|
console.log(
|
|
10023
10105
|
` Confidence (${confidenceBasisLabel(decision.basis)}): ${verdictWithheld ? "withheld \u2014 not decision-grade" : formatPct(decision.judgedConfidence)}`
|
|
10024
10106
|
);
|
|
10025
|
-
const arms =
|
|
10107
|
+
const arms = summary.arms;
|
|
10026
10108
|
if (arms.length > 0) {
|
|
10027
10109
|
console.log();
|
|
10028
10110
|
printTable(
|
|
@@ -10040,7 +10122,7 @@ function printExperimentResults(results2, currency) {
|
|
|
10040
10122
|
[32, 8, 6, 8, 10]
|
|
10041
10123
|
);
|
|
10042
10124
|
}
|
|
10043
|
-
const metrics =
|
|
10125
|
+
const metrics = summary.metrics;
|
|
10044
10126
|
if (metrics.length > 0) {
|
|
10045
10127
|
console.log();
|
|
10046
10128
|
console.log(source_default.bold("Goal counting"));
|
|
@@ -10050,7 +10132,7 @@ function printExperimentResults(results2, currency) {
|
|
|
10050
10132
|
});
|
|
10051
10133
|
}
|
|
10052
10134
|
console.log(" Definitions: https://docs.drip-apex.com/docs/experiments/metric-definitions");
|
|
10053
|
-
const warnings =
|
|
10135
|
+
const warnings = summary.warnings;
|
|
10054
10136
|
if (warnings.length > 0) {
|
|
10055
10137
|
console.log();
|
|
10056
10138
|
console.log(source_default.yellow("Warnings"));
|
|
@@ -10353,10 +10435,10 @@ function printQaRun(run3) {
|
|
|
10353
10435
|
}
|
|
10354
10436
|
if ((run3.evidenceRecords ?? []).length > 0) {
|
|
10355
10437
|
console.log(source_default.bold("\nEvidence records"));
|
|
10356
|
-
for (const
|
|
10357
|
-
const device =
|
|
10438
|
+
for (const record4 of run3.evidenceRecords ?? []) {
|
|
10439
|
+
const device = record4.device ? ` \xB7 ${record4.device}` : "";
|
|
10358
10440
|
console.log(
|
|
10359
|
-
` - ${
|
|
10441
|
+
` - ${record4.kind} \xB7 ${record4.label} \xB7 ${record4.status}${device} \xB7 ${record4.capturedAt}${qaVersionMarker(record4)}`
|
|
10360
10442
|
);
|
|
10361
10443
|
}
|
|
10362
10444
|
}
|
|
@@ -10475,26 +10557,29 @@ async function refreshServerOwnedFilesIfNeeded(creds, folder, experimentId, upda
|
|
|
10475
10557
|
}
|
|
10476
10558
|
}
|
|
10477
10559
|
var EXPERIMENT_REFERENCE_DESCRIPTION = "Experiment ID, slug, or test key (for example BIO-085)";
|
|
10560
|
+
function resolveCliExperimentReference(creds, reference, variationRef) {
|
|
10561
|
+
return resolveExperimentReference(
|
|
10562
|
+
(_method, requestPath) => {
|
|
10563
|
+
const prefix = "/api/v1/experiments/by-slug/";
|
|
10564
|
+
const bySlug = requestPath.startsWith(prefix);
|
|
10565
|
+
const idOrSlug = decodeURIComponent(
|
|
10566
|
+
requestPath.slice(bySlug ? prefix.length : "/api/v1/experiments/".length)
|
|
10567
|
+
);
|
|
10568
|
+
return bySlug ? getExperimentBySlug(creds, idOrSlug) : getExperiment(creds, idOrSlug);
|
|
10569
|
+
},
|
|
10570
|
+
reference,
|
|
10571
|
+
variationRef
|
|
10572
|
+
);
|
|
10573
|
+
}
|
|
10478
10574
|
async function resolveExperiment(idOrSlug) {
|
|
10479
10575
|
const creds = requireCredentials();
|
|
10480
|
-
|
|
10481
|
-
|
|
10482
|
-
if (res2.ok) return res2.data;
|
|
10483
|
-
throw new CliError(
|
|
10484
|
-
res2.status === 404 && isTestKeyReference(idOrSlug) ? `Experiment "${idOrSlug}" not found in selected shop ${creds.resolvedContext?.shopId ?? "(API key shop)"}. Test keys resolve within the selected shop; use --shop <shop-id> to change it.` : res2.error ?? `Experiment "${idOrSlug}" not found`,
|
|
10485
|
-
classifyStatus(res2.status),
|
|
10486
|
-
res2.errorDetails,
|
|
10487
|
-
apiFailureOf(res2)
|
|
10488
|
-
);
|
|
10489
|
-
}
|
|
10490
|
-
const slug = idOrSlug.startsWith("slug:") ? idOrSlug.slice(5) : idOrSlug;
|
|
10491
|
-
const res = await getExperimentBySlug(creds, slug);
|
|
10492
|
-
if (res.ok) return res.data;
|
|
10576
|
+
const res = await resolveCliExperimentReference(creds, idOrSlug);
|
|
10577
|
+
if (res.ok) return res.experiment;
|
|
10493
10578
|
throw new CliError(
|
|
10494
|
-
res.error ?? `Experiment "${idOrSlug}" not found
|
|
10495
|
-
classifyStatus(res.status),
|
|
10496
|
-
res.errorDetails,
|
|
10497
|
-
apiFailureOf(res)
|
|
10579
|
+
res.status === 404 && isExperimentTestKey(idOrSlug) ? `Experiment "${idOrSlug}" not found in selected shop ${creds.resolvedContext?.shopId ?? "(API key shop)"}. Test keys resolve within the selected shop; use --shop <shop-id> to change it.` : res.response ? res.response.error ?? `Experiment "${idOrSlug}" not found` : res.error,
|
|
10580
|
+
classifyStatus(res.status ?? 500),
|
|
10581
|
+
res.response?.errorDetails,
|
|
10582
|
+
res.response ? apiFailureOf(res.response) : void 0
|
|
10498
10583
|
);
|
|
10499
10584
|
}
|
|
10500
10585
|
var list = new Command("list").alias("ls").description(
|
|
@@ -12114,7 +12199,7 @@ var qaEvidence = new Command("evidence").description("Attach screenshot jobs or
|
|
|
12114
12199
|
classifyStatus(current.status),
|
|
12115
12200
|
current.errorDetails
|
|
12116
12201
|
);
|
|
12117
|
-
for (const
|
|
12202
|
+
for (const record4 of current.data.run.evidenceRecords) previousIds.add(record4.id);
|
|
12118
12203
|
}
|
|
12119
12204
|
let response;
|
|
12120
12205
|
if (opts.job) {
|
|
@@ -12159,7 +12244,7 @@ var qaEvidence = new Command("evidence").description("Attach screenshot jobs or
|
|
|
12159
12244
|
const run3 = response.data.run;
|
|
12160
12245
|
const data = opts.summary ? qaSummary(
|
|
12161
12246
|
run3,
|
|
12162
|
-
run3.evidenceRecords.filter((
|
|
12247
|
+
run3.evidenceRecords.filter((record4) => !previousIds.has(record4.id))
|
|
12163
12248
|
) : response.data;
|
|
12164
12249
|
output(this, data, () => {
|
|
12165
12250
|
if (opts.summary) process.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
@@ -15362,18 +15447,18 @@ function fieldsFrom(value, prefix = "", descriptorList = false) {
|
|
|
15362
15447
|
)
|
|
15363
15448
|
);
|
|
15364
15449
|
}
|
|
15365
|
-
const
|
|
15366
|
-
const explicitPath = typeof
|
|
15450
|
+
const record4 = value;
|
|
15451
|
+
const explicitPath = typeof record4.path === "string" ? record4.path : void 0;
|
|
15367
15452
|
if (descriptorList && explicitPath) {
|
|
15368
|
-
const rawValues =
|
|
15453
|
+
const rawValues = record4.values ?? record4.samples ?? record4.examples ?? record4.example;
|
|
15369
15454
|
const values = Array.isArray(rawValues) ? rawValues : rawValues === void 0 ? [] : [rawValues];
|
|
15370
|
-
const magnitude = [
|
|
15455
|
+
const magnitude = [record4.mean, record4.average, record4.max, record4.magnitude].find(
|
|
15371
15456
|
(candidate) => typeof candidate === "number"
|
|
15372
15457
|
);
|
|
15373
|
-
const numericType = Array.isArray(
|
|
15458
|
+
const numericType = Array.isArray(record4.types) && record4.types.length > 0 && record4.types.every((type) => type === "num" || type === "numstr" || type === "numstr_comma");
|
|
15374
15459
|
return [{ path: runtimePath(explicitPath), values, magnitude, numericType }];
|
|
15375
15460
|
}
|
|
15376
|
-
return Object.entries(
|
|
15461
|
+
return Object.entries(record4).flatMap(([key, child]) => {
|
|
15377
15462
|
if (["eventName", "event_name", "name", "count", "frequency", "evidence"].includes(key))
|
|
15378
15463
|
return [];
|
|
15379
15464
|
const next = prefix ? `${prefix}.${key}` : key;
|
|
@@ -15406,8 +15491,8 @@ function isDescriptorArray(value) {
|
|
|
15406
15491
|
]);
|
|
15407
15492
|
return Array.isArray(value) && value.length > 0 && value.every((item) => {
|
|
15408
15493
|
if (!item || typeof item !== "object" || Array.isArray(item)) return false;
|
|
15409
|
-
const
|
|
15410
|
-
return typeof
|
|
15494
|
+
const record4 = item;
|
|
15495
|
+
return typeof record4.path === "string" && record4.path.length > 0 && Object.keys(record4).every((key) => descriptorKeys.has(key));
|
|
15411
15496
|
});
|
|
15412
15497
|
}
|
|
15413
15498
|
function candidatesFrom(report) {
|
|
@@ -15563,10 +15648,10 @@ var whenOps = new Set(runtime_settings_trigger_constants_default.whenOps);
|
|
|
15563
15648
|
function strictObject(value, location, keys) {
|
|
15564
15649
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
15565
15650
|
throw new Error(`${location} must be an object`);
|
|
15566
|
-
const
|
|
15567
|
-
for (const key of Object.keys(
|
|
15651
|
+
const record4 = value;
|
|
15652
|
+
for (const key of Object.keys(record4))
|
|
15568
15653
|
if (!keys.has(key)) throw new Error(`${location}.${key} is not allowed`);
|
|
15569
|
-
return
|
|
15654
|
+
return record4;
|
|
15570
15655
|
}
|
|
15571
15656
|
function optionalType(value, type, location) {
|
|
15572
15657
|
if (value !== void 0 && typeof value !== type)
|
|
@@ -15702,19 +15787,19 @@ function strictTriggers(value) {
|
|
|
15702
15787
|
return value.map((item, index) => {
|
|
15703
15788
|
if (!item || typeof item !== "object" || Array.isArray(item))
|
|
15704
15789
|
throw new Error(`trigger[${index}] must be an object`);
|
|
15705
|
-
const
|
|
15706
|
-
for (const key of Object.keys(
|
|
15790
|
+
const record4 = item;
|
|
15791
|
+
for (const key of Object.keys(record4))
|
|
15707
15792
|
if (!allowed.has(key)) throw new Error(`trigger[${index}].${key} is not allowed`);
|
|
15708
|
-
if (typeof
|
|
15793
|
+
if (typeof record4.eventName !== "string" || !record4.eventName.trim())
|
|
15709
15794
|
throw new Error(`trigger[${index}].eventName must be a non-empty string`);
|
|
15710
15795
|
for (const key of ["enabled", "reEvaluate", "trackPageview"])
|
|
15711
|
-
optionalType(
|
|
15796
|
+
optionalType(record4[key], "boolean", `trigger[${index}].${key}`);
|
|
15712
15797
|
for (const key of ["dataLayerName", "trackEventName"])
|
|
15713
|
-
optionalType(
|
|
15714
|
-
strictWhen(
|
|
15715
|
-
if (
|
|
15798
|
+
optionalType(record4[key], "string", `trigger[${index}].${key}`);
|
|
15799
|
+
strictWhen(record4.when, `trigger[${index}].when`);
|
|
15800
|
+
if (record4.trackRevenue !== void 0) {
|
|
15716
15801
|
const revenue = strictObject(
|
|
15717
|
-
|
|
15802
|
+
record4.trackRevenue,
|
|
15718
15803
|
`trigger[${index}].trackRevenue`,
|
|
15719
15804
|
/* @__PURE__ */ new Set([
|
|
15720
15805
|
"enabled",
|
|
@@ -15737,21 +15822,21 @@ function strictTriggers(value) {
|
|
|
15737
15822
|
);
|
|
15738
15823
|
}
|
|
15739
15824
|
}
|
|
15740
|
-
if (
|
|
15741
|
-
if (!Array.isArray(
|
|
15825
|
+
if (record4.mappings !== void 0) {
|
|
15826
|
+
if (!Array.isArray(record4.mappings))
|
|
15742
15827
|
throw new Error(`trigger[${index}].mappings must be an array`);
|
|
15743
|
-
|
|
15828
|
+
record4.mappings.forEach(
|
|
15744
15829
|
(mapping, mappingIndex) => strictMapping(mapping, `trigger[${index}].mappings[${mappingIndex}]`, false)
|
|
15745
15830
|
);
|
|
15746
15831
|
}
|
|
15747
|
-
if (
|
|
15748
|
-
if (!Array.isArray(
|
|
15832
|
+
if (record4.properties !== void 0) {
|
|
15833
|
+
if (!Array.isArray(record4.properties))
|
|
15749
15834
|
throw new Error(`trigger[${index}].properties must be an array`);
|
|
15750
|
-
|
|
15835
|
+
record4.properties.forEach(
|
|
15751
15836
|
(mapping, mappingIndex) => strictMapping(mapping, `trigger[${index}].properties[${mappingIndex}]`, true)
|
|
15752
15837
|
);
|
|
15753
15838
|
}
|
|
15754
|
-
return
|
|
15839
|
+
return record4;
|
|
15755
15840
|
});
|
|
15756
15841
|
}
|
|
15757
15842
|
function writeWarnings(result) {
|
|
@@ -16280,7 +16365,7 @@ function compare(a, b) {
|
|
|
16280
16365
|
const left = a.fraction.padEnd(precision, "0"), right = b.fraction.padEnd(precision, "0");
|
|
16281
16366
|
return left === right ? 0 : left < right ? -1 : 1;
|
|
16282
16367
|
}
|
|
16283
|
-
var
|
|
16368
|
+
var record2 = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
16284
16369
|
var text = (v) => typeof v === "string" && v.length > 0;
|
|
16285
16370
|
var reason = (v) => typeof v === "string" && (/^[a-z][a-z0-9_]{0,79}$/.test(v) || /^(publishedConfig|consentPolicy|goalMapping|sdkArtifact|sdkPolicy|identityPolicy|goalDefinition|resultWindow|inputSnapshot)_(expected_unknown|observed_unknown|mismatch|binding_mismatch)$/.test(
|
|
16286
16371
|
v
|
|
@@ -16289,8 +16374,8 @@ var member = (v, values) => typeof v === "string" && values.includes(v);
|
|
|
16289
16374
|
var status = (v) => member(v, ["pass", "fail", "inconclusive"]);
|
|
16290
16375
|
var count = (v) => typeof v === "number" && Number.isSafeInteger(v) && v >= 0;
|
|
16291
16376
|
function validReport(v) {
|
|
16292
|
-
if (!
|
|
16293
|
-
(s) =>
|
|
16377
|
+
if (!record2(v) || v.schemaVersion !== 1 || v.finalStatisticalContribution !== "not_evaluated" || !record2(v.evaluation) || !status(v.evaluation.status) || !member(v.evaluation.freshness, ["current", "stale", "unknown"]) || !Array.isArray(v.evaluation.stages) || !v.evaluation.stages.every(
|
|
16378
|
+
(s) => record2(s) && (s.freshness === void 0 || member(s.freshness, ["current", "stale", "unknown"])) && member(s.stage, [
|
|
16294
16379
|
"consent",
|
|
16295
16380
|
"assignment",
|
|
16296
16381
|
"event",
|
|
@@ -16302,17 +16387,17 @@ function validReport(v) {
|
|
|
16302
16387
|
))
|
|
16303
16388
|
return false;
|
|
16304
16389
|
if (v.receiptOutcomes !== void 0 && (!Array.isArray(v.receiptOutcomes) || v.receiptOutcomes.length > 6856 || !v.receiptOutcomes.every(
|
|
16305
|
-
(r) =>
|
|
16390
|
+
(r) => record2(r) && text(r.receiptId) && text(r.stage) && text(r.producerContract) && record2(r.scope) && [r.scope.experimentId, r.scope.variationId, r.scope.goalId].every(
|
|
16306
16391
|
(x) => x === null || text(x)
|
|
16307
16392
|
) && member(r.freshness, ["current", "stale", "unknown"]) && Array.isArray(r.reasonCodes) && r.reasonCodes.every(reason)
|
|
16308
16393
|
)))
|
|
16309
16394
|
return false;
|
|
16310
16395
|
const coverage = v.assignmentCoverage;
|
|
16311
|
-
if (!
|
|
16396
|
+
if (!record2(coverage) || typeof coverage.complete !== "boolean" || typeof coverage.overflowCountIsLowerBound !== "boolean" || !(coverage.overflowCount === null || count(coverage.overflowCount)))
|
|
16312
16397
|
return false;
|
|
16313
16398
|
return Array.isArray(v.assignments) && v.assignments.length <= 50 && v.assignments.every(
|
|
16314
|
-
(a) =>
|
|
16315
|
-
(g) =>
|
|
16399
|
+
(a) => record2(a) && text(a.experimentId) && text(a.variationId) && (a.storedAttribution === null || typeof a.storedAttribution === "boolean") && reason(a.reasonCode) && Array.isArray(a.goals) && a.goals.length <= 50 && a.goals.every(
|
|
16400
|
+
(g) => record2(g) && text(g.goalId) && member(g.status, [
|
|
16316
16401
|
"eligible_for_attributed_goal_read",
|
|
16317
16402
|
"excluded_from_attributed_goal_read",
|
|
16318
16403
|
"unknown"
|
|
@@ -16683,7 +16768,7 @@ var PURCHASE_CADENCE_WINDOW_MINUTES = PURCHASE_WINDOW_MINUTES * 4;
|
|
|
16683
16768
|
var MIN_CAPTURE_WINDOW_MINUTES = 60;
|
|
16684
16769
|
var DUPLICATE_RATE_THRESHOLD = 0.02;
|
|
16685
16770
|
var MAGNITUDE_TOLERANCE_RATE = 0.1;
|
|
16686
|
-
function
|
|
16771
|
+
function record3(value) {
|
|
16687
16772
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
16688
16773
|
}
|
|
16689
16774
|
function purchasePlane(config) {
|
|
@@ -16691,8 +16776,8 @@ function purchasePlane(config) {
|
|
|
16691
16776
|
const names = [];
|
|
16692
16777
|
const triggers = config.runtime?.dataLayerTriggers ?? config.dataLayerTriggers;
|
|
16693
16778
|
if (Array.isArray(triggers) && triggers.some((trigger) => {
|
|
16694
|
-
const row =
|
|
16695
|
-
const trackRevenue =
|
|
16779
|
+
const row = record3(trigger);
|
|
16780
|
+
const trackRevenue = record3(row?.trackRevenue);
|
|
16696
16781
|
return row?.enabled !== false && trackRevenue !== null && trackRevenue.enabled !== false;
|
|
16697
16782
|
}))
|
|
16698
16783
|
names.push("dataLayer trigger");
|
|
@@ -16734,7 +16819,7 @@ function lineItemSum(value) {
|
|
|
16734
16819
|
if (!Array.isArray(value)) return null;
|
|
16735
16820
|
let sum = 0;
|
|
16736
16821
|
for (const item of value) {
|
|
16737
|
-
const row =
|
|
16822
|
+
const row = record3(item);
|
|
16738
16823
|
const price = numeric(row?.price);
|
|
16739
16824
|
if (price === null) return null;
|
|
16740
16825
|
sum += price * (numeric(row?.quantity) ?? 1);
|
|
@@ -18274,10 +18359,10 @@ function getEdgeDeliveryStatus(deliveryType, expectedWorstCaseSeconds = 360) {
|
|
|
18274
18359
|
return deliveryType === "api" ? { edge_delivery: "not_applicable", message: `API-delivered flag \u2014 edge delivery is not applicable. A previously cached visual payload may remain at some PoPs for up to ~${expectedWorstCaseSeconds}s; a single-vantage status cannot prove global propagation.` } : { edge_delivery: "applicable", message: null };
|
|
18275
18360
|
}
|
|
18276
18361
|
function parsePublicationMetadata(value) {
|
|
18277
|
-
const
|
|
18362
|
+
const record4 = value && typeof value === "object" ? value : {};
|
|
18278
18363
|
return {
|
|
18279
|
-
publication_revision: Number.isSafeInteger(
|
|
18280
|
-
generated_at: typeof
|
|
18364
|
+
publication_revision: Number.isSafeInteger(record4.publication_revision) && record4.publication_revision >= 0 ? record4.publication_revision : null,
|
|
18365
|
+
generated_at: typeof record4.generated_at === "string" && !Number.isNaN(Date.parse(record4.generated_at)) ? record4.generated_at : null
|
|
18281
18366
|
};
|
|
18282
18367
|
}
|
|
18283
18368
|
function compareEdgePublication(currentValue, edgeValue, expectedWorstCaseSeconds, flagUpdatedAtValue, confirmedAt = (/* @__PURE__ */ new Date()).toISOString()) {
|