@revturbine/cli 0.16.3 → 0.16.4
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 +43 -2
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1869,7 +1869,14 @@ var ClientContextCapabilitiesSchema = z9.object({
|
|
|
1869
1869
|
);
|
|
1870
1870
|
var ClientContextPlanSchema = z9.object({
|
|
1871
1871
|
/** The customer's current plan handle (`plans.unique_handle`). */
|
|
1872
|
-
handle: z9.string().min(1).optional().meta({ ...Unrestricted6, ...ClientSafe })
|
|
1872
|
+
handle: z9.string().min(1).optional().meta({ ...Unrestricted6, ...ClientSafe }),
|
|
1873
|
+
/**
|
|
1874
|
+
* The plan's display name, resolved server-side from the plan record so
|
|
1875
|
+
* client UI can render it without a Playbook lookup (plan 179 TASK-1 —
|
|
1876
|
+
* Q-2 ruling: `{ handle, name }`). Plan names are already client-visible
|
|
1877
|
+
* in every Playbook; no new exposure.
|
|
1878
|
+
*/
|
|
1879
|
+
name: z9.string().min(1).optional().meta({ ...Unrestricted6, ...ClientSafe })
|
|
1873
1880
|
}).meta(
|
|
1874
1881
|
{ id: "ClientContextPlan", "x-revturbine-schema-persistence": Transient6, "x-revturbine-schema-exposure": Internal5 }
|
|
1875
1882
|
);
|
|
@@ -5940,6 +5947,18 @@ var CATALOG = {
|
|
|
5940
5947
|
message: "These rules for the same entitlement target the same plan and segment \u2014 only one will apply.",
|
|
5941
5948
|
specRef: "config-validation.md \xA75.3 (provisional \u2014 plan 73 Q-1)"
|
|
5942
5949
|
},
|
|
5950
|
+
// limit rule with unset enforcement. Promoted from §5.8 (plan 179 Q-6,
|
|
5951
|
+
// Kent 2026-08-12): unset enforcement silently means "hard-block at the
|
|
5952
|
+
// cap" (evaluator default since plan 34) — an author who wanted degrade or
|
|
5953
|
+
// allow_overage gets a hard stop without being told. Explicitness warn on
|
|
5954
|
+
// the corrected premise (the old "never blocks" mechanism was the SDK
|
|
5955
|
+
// ignoring allowed:false, fixed in sdk 0.2.75).
|
|
5956
|
+
"VAL-PLN-07": {
|
|
5957
|
+
id: "VAL-PLN-07",
|
|
5958
|
+
severity: "warning",
|
|
5959
|
+
message: "This limit rule sets no enforcement \u2014 at the cap it blocks by default. Set enforcement explicitly (hard_block, soft_block, degrade, allow_overage) if that isn't the intent.",
|
|
5960
|
+
specRef: "config-validation.md \xA75.8 (promoted \u2014 plan 179 Q-6)"
|
|
5961
|
+
},
|
|
5943
5962
|
// multiple public variations. Origin: `*_variation.multiple_public`.
|
|
5944
5963
|
"VAL-PLN-06": {
|
|
5945
5964
|
id: "VAL-PLN-06",
|
|
@@ -5976,11 +5995,33 @@ function runSemanticRules(graph) {
|
|
|
5976
5995
|
return [
|
|
5977
5996
|
...checkPlansHaveStripePrice(graph),
|
|
5978
5997
|
...checkRuleOverlaps(graph),
|
|
5998
|
+
...checkLimitRuleEnforcement(graph),
|
|
5979
5999
|
...checkPublicVariationCollisions(graph),
|
|
5980
6000
|
...checkPayloadCtaOverflow(graph),
|
|
5981
6001
|
...checkTrialRuleWidestAudience(graph)
|
|
5982
6002
|
];
|
|
5983
6003
|
}
|
|
6004
|
+
function checkLimitRuleEnforcement(graph) {
|
|
6005
|
+
const findings = [];
|
|
6006
|
+
const CAP_FIELDS = ["limit_value", "allowance_value", "included_count"];
|
|
6007
|
+
for (const rule of graph.entitlement_rules ?? []) {
|
|
6008
|
+
if (rule.enforcement !== void 0 && rule.enforcement !== null) continue;
|
|
6009
|
+
const cappedField = CAP_FIELDS.find((f) => typeof rule[f] === "number" && Number.isFinite(rule[f]));
|
|
6010
|
+
if (!cappedField) continue;
|
|
6011
|
+
const id = String(rule.handle ?? rule.id ?? "");
|
|
6012
|
+
const name = String(rule.name ?? id);
|
|
6013
|
+
findings.push(
|
|
6014
|
+
finding(
|
|
6015
|
+
"VAL-PLN-07",
|
|
6016
|
+
{ object_type: "entitlement_rule", object_id: id, field: "enforcement", studio: "plans-entitlements" },
|
|
6017
|
+
{
|
|
6018
|
+
message: `Limit rule '${name}' sets no enforcement \u2014 at the cap it blocks by default. Set enforcement explicitly (hard_block, soft_block, degrade, allow_overage) if that isn't the intent.`
|
|
6019
|
+
}
|
|
6020
|
+
)
|
|
6021
|
+
);
|
|
6022
|
+
}
|
|
6023
|
+
return findings;
|
|
6024
|
+
}
|
|
5984
6025
|
function surfaceCtas(surface) {
|
|
5985
6026
|
if (!surface || typeof surface !== "object") return 0;
|
|
5986
6027
|
const ctas = surface.ctas;
|
|
@@ -8923,7 +8964,7 @@ function repairDeprecatedFields(config, schema = PlaybookObjectSchema2) {
|
|
|
8923
8964
|
}
|
|
8924
8965
|
|
|
8925
8966
|
// src/schema/version.ts
|
|
8926
|
-
var SCHEMA_VERSION = "0.1.
|
|
8967
|
+
var SCHEMA_VERSION = "0.1.168";
|
|
8927
8968
|
|
|
8928
8969
|
// src/lib/credentials.ts
|
|
8929
8970
|
import { chmodSync, existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "fs";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@revturbine/cli",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.4",
|
|
4
4
|
"description": "revturbine — validate RevTurbine Playbooks and ship them to a RevTurbine instance through the playbook-version lifecycle (draft → Release).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|