@revturbine/cli 0.21.1 → 0.21.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 +614 -548
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -2284,10 +2284,20 @@ var DEFAULT_TEMPLATE_COMPONENT_TYPES = {
|
|
|
2284
2284
|
agent_connector: "agent",
|
|
2285
2285
|
custom_in_app: "custom"
|
|
2286
2286
|
};
|
|
2287
|
+
var LEGACY_TEMPLATE_ALIASES = Object.freeze({
|
|
2288
|
+
plans_pricing_ctas: "plans_page_ctas",
|
|
2289
|
+
plans_pricing_full: "plans_page_full",
|
|
2290
|
+
credit_balance_counter: "credit_counter",
|
|
2291
|
+
banner_placement: "banner",
|
|
2292
|
+
modal_overlay: "modal_optional",
|
|
2293
|
+
toast_message: "toast",
|
|
2294
|
+
push_notification: "push"
|
|
2295
|
+
});
|
|
2287
2296
|
var BUILT_IN_TEMPLATE_COMPONENT_TYPES = Object.freeze({
|
|
2288
2297
|
...DEFAULT_TEMPLATE_COMPONENT_TYPES,
|
|
2289
|
-
|
|
2290
|
-
|
|
2298
|
+
...Object.fromEntries(
|
|
2299
|
+
Object.entries(LEGACY_TEMPLATE_ALIASES).map(([legacy, id11]) => [legacy, DEFAULT_TEMPLATE_COMPONENT_TYPES[id11]])
|
|
2300
|
+
),
|
|
2291
2301
|
full_page: "full_page"
|
|
2292
2302
|
});
|
|
2293
2303
|
var ENTITLEMENT_STATUS_VALUES = ["allowed", "limited", "denied"];
|
|
@@ -21713,9 +21723,9 @@ var SimulationRunReceiptSchema = z68.strictObject({
|
|
|
21713
21723
|
|
|
21714
21724
|
// src/schema/validators.snapshot.mjs
|
|
21715
21725
|
import { z as z69 } from "zod";
|
|
21716
|
-
import { z as z92 } from "zod";
|
|
21717
21726
|
import { z as z310 } from "zod";
|
|
21718
21727
|
import { z as z210 } from "zod";
|
|
21728
|
+
import { z as z92 } from "zod";
|
|
21719
21729
|
import { z as z410 } from "zod";
|
|
21720
21730
|
import { z as z610 } from "zod";
|
|
21721
21731
|
import { z as z510 } from "zod";
|
|
@@ -21897,6 +21907,15 @@ var CATALOG = {
|
|
|
21897
21907
|
message: "This payload names a placement that does not exist.",
|
|
21898
21908
|
specRef: "config-validation.md \xA75.9 (BL-0180, D-31)"
|
|
21899
21909
|
},
|
|
21910
|
+
// payload surface → template (BUG-1345): a template id that is neither
|
|
21911
|
+
// built-in (incl. legacy aliases) nor authored in `surface_templates` has no
|
|
21912
|
+
// rendering type, so every SDK skips that payload at load.
|
|
21913
|
+
"VAL-PLC-11": {
|
|
21914
|
+
id: "VAL-PLC-11",
|
|
21915
|
+
severity: "error_launch",
|
|
21916
|
+
message: "This payload uses a surface template that does not exist.",
|
|
21917
|
+
specRef: "config-validation.md \xA75.2 (BUG-1345)"
|
|
21918
|
+
},
|
|
21900
21919
|
"VAL-PLN-08": {
|
|
21901
21920
|
id: "VAL-PLN-08",
|
|
21902
21921
|
severity: "error_launch",
|
|
@@ -21978,193 +21997,465 @@ function categoryBucket(category) {
|
|
|
21978
21997
|
if (normalized.includes("retention") || normalized.includes("winback") || normalized.includes("churn")) return 4;
|
|
21979
21998
|
return 99;
|
|
21980
21999
|
}
|
|
21981
|
-
|
|
21982
|
-
|
|
21983
|
-
|
|
21984
|
-
|
|
21985
|
-
|
|
21986
|
-
|
|
21987
|
-
|
|
21988
|
-
|
|
21989
|
-
|
|
21990
|
-
|
|
22000
|
+
var HANDLE_PATTERN2 = /^[a-z0-9._]{1,100}$/;
|
|
22001
|
+
var SchemaPersistence2 = {
|
|
22002
|
+
Persisted: "persisted",
|
|
22003
|
+
Transient: "transient"
|
|
22004
|
+
};
|
|
22005
|
+
var SchemaExposure2 = {
|
|
22006
|
+
Internal: "internal",
|
|
22007
|
+
External: "external"
|
|
22008
|
+
};
|
|
22009
|
+
var DataClassification2 = {
|
|
22010
|
+
Pii: { "x-revturbine-data-classification": "pii" },
|
|
22011
|
+
Financial: { "x-revturbine-data-classification": "financial" },
|
|
22012
|
+
Unrestricted: { "x-revturbine-data-classification": "unrestricted" },
|
|
22013
|
+
/**
|
|
22014
|
+
* Machine-generated evaluation exhaust — supersession records, entitlement
|
|
22015
|
+
* grants, placement decision traces. Carries no personal or financial data
|
|
22016
|
+
* itself, but describes what the engine decided about a user, so it is not
|
|
22017
|
+
* `Unrestricted` either. Applied at the MODEL level (plan 182 REQ-7); it was
|
|
22018
|
+
* already in use as a raw string literal on four schemas before being
|
|
22019
|
+
* declared here, which left `DataClassificationValue` unable to represent it.
|
|
22020
|
+
*/
|
|
22021
|
+
Operational: { "x-revturbine-data-classification": "operational" }
|
|
22022
|
+
};
|
|
22023
|
+
var SCHEMA_EXPOSURE_META_KEY2 = "x-revturbine-schema-exposure";
|
|
22024
|
+
var READ_ONLY_META_KEY2 = "readOnly";
|
|
22025
|
+
var DECISION_ONLY_META_KEY2 = "x-revturbine-decision-only";
|
|
22026
|
+
var DecisionOnly2 = { [DECISION_ONLY_META_KEY2]: true };
|
|
22027
|
+
var ClientSafe2 = { [SCHEMA_EXPOSURE_META_KEY2]: SchemaExposure2.External };
|
|
22028
|
+
var ServerOnly2 = { [SCHEMA_EXPOSURE_META_KEY2]: SchemaExposure2.Internal };
|
|
22029
|
+
function toWritableSchema2(schema) {
|
|
22030
|
+
const writableShape = {};
|
|
22031
|
+
for (const [fieldName, fieldSchema] of Object.entries(schema.shape)) {
|
|
22032
|
+
if (typeof fieldSchema !== "object" || fieldSchema === null) {
|
|
22033
|
+
continue;
|
|
22034
|
+
}
|
|
22035
|
+
const isReadOnly = fieldSchema.meta()?.[READ_ONLY_META_KEY2] === true;
|
|
22036
|
+
if (!isReadOnly) {
|
|
22037
|
+
writableShape[fieldName] = fieldSchema;
|
|
22038
|
+
}
|
|
21991
22039
|
}
|
|
21992
|
-
|
|
21993
|
-
if (raw === "per_6_hours" || raw === "six_hours") return "six_hours";
|
|
21994
|
-
return raw.startsWith("per_") ? raw.slice(4) : raw;
|
|
22040
|
+
return z210.object(writableShape);
|
|
21995
22041
|
}
|
|
21996
|
-
function
|
|
21997
|
-
const
|
|
21998
|
-
const
|
|
21999
|
-
if (
|
|
22000
|
-
|
|
22042
|
+
function toCreateSchema2(schema) {
|
|
22043
|
+
const writable = toWritableSchema2(schema);
|
|
22044
|
+
const handleField = writable.shape["handle"];
|
|
22045
|
+
if (handleField && typeof handleField.regex === "function") {
|
|
22046
|
+
return writable.extend({ handle: handleField.regex(HANDLE_PATTERN2) });
|
|
22001
22047
|
}
|
|
22048
|
+
return writable;
|
|
22002
22049
|
}
|
|
22003
|
-
var
|
|
22004
|
-
var
|
|
22005
|
-
var
|
|
22006
|
-
var
|
|
22007
|
-
|
|
22008
|
-
|
|
22009
|
-
|
|
22010
|
-
|
|
22011
|
-
|
|
22012
|
-
|
|
22013
|
-
|
|
22014
|
-
|
|
22015
|
-
values: values.map(([value, valueName, legacyValue]) => ({
|
|
22016
|
-
value,
|
|
22017
|
-
name: valueName,
|
|
22018
|
-
legacyPickerId: `${legacyPrefix}${legacyValue ?? value}`
|
|
22019
|
-
})),
|
|
22020
|
-
...opts.fallback !== void 0 ? { fallback: opts.fallback } : {},
|
|
22021
|
-
legacyPrefix
|
|
22022
|
-
};
|
|
22023
|
-
}
|
|
22024
|
-
var BUILTIN_DIMENSIONS2 = [
|
|
22025
|
-
dimension2("registration_state", "Registration State", "reg", [
|
|
22026
|
-
["unregistered", "Unregistered"],
|
|
22027
|
-
["registered", "Registered"]
|
|
22028
|
-
]),
|
|
22029
|
-
dimension2(
|
|
22030
|
-
"activity_level",
|
|
22031
|
-
"Activity State",
|
|
22032
|
-
"act",
|
|
22033
|
-
[
|
|
22034
|
-
["new", "New"],
|
|
22035
|
-
["high", "High Activity"],
|
|
22036
|
-
["medium", "Medium Activity"],
|
|
22037
|
-
["low", "Low Activity"],
|
|
22038
|
-
["inactive", "Inactive"]
|
|
22039
|
-
],
|
|
22040
|
-
{ fallback: "new" }
|
|
22041
|
-
),
|
|
22042
|
-
dimension2(
|
|
22043
|
-
"subscription_state",
|
|
22044
|
-
"Subscription State",
|
|
22045
|
-
"sub",
|
|
22046
|
-
[
|
|
22047
|
-
["none", "None"],
|
|
22048
|
-
["trial", "Trial"],
|
|
22049
|
-
["paid", "Paid"],
|
|
22050
|
-
["cancelled", "Cancelled"]
|
|
22051
|
-
],
|
|
22052
|
-
{ fallback: "none" }
|
|
22053
|
-
),
|
|
22054
|
-
dimension2(
|
|
22055
|
-
"trial_type",
|
|
22056
|
-
"Trial Type",
|
|
22057
|
-
"trial",
|
|
22058
|
-
[
|
|
22059
|
-
["none", "Not in trial"],
|
|
22060
|
-
["free_trial", "Free trial", "free"],
|
|
22061
|
-
["reverse_trial", "Reverse trial", "reverse"]
|
|
22062
|
-
],
|
|
22063
|
-
{ fallback: "none" }
|
|
22064
|
-
),
|
|
22065
|
-
dimension2("seat_type", "Seat Type", "seat", [], { vocabulary: "seat_type" }),
|
|
22066
|
-
dimension2("buyer_role", "Buyer Role", "role", [
|
|
22067
|
-
["buyer", "Buyer"],
|
|
22068
|
-
["non_buyer", "Non-buyer"]
|
|
22069
|
-
]),
|
|
22070
|
-
dimension2(
|
|
22071
|
-
"email_type",
|
|
22072
|
-
"Email Type",
|
|
22073
|
-
"email",
|
|
22074
|
-
[
|
|
22075
|
-
["business", "Business email"],
|
|
22076
|
-
["personal", "Personal email"],
|
|
22077
|
-
["unknown", "Unknown"]
|
|
22078
|
-
],
|
|
22079
|
-
{ fallback: "unknown" }
|
|
22080
|
-
),
|
|
22081
|
-
dimension2(
|
|
22082
|
-
"billing_health",
|
|
22083
|
-
"Billing Health",
|
|
22084
|
-
"bill",
|
|
22085
|
-
[
|
|
22086
|
-
["no_billing", "No billing", "none"],
|
|
22087
|
-
["good_standing", "Good standing", "good"],
|
|
22088
|
-
["trial_payment_method_attached", "Trial \u2014 payment method attached", "trial_pm"],
|
|
22089
|
-
["payment_method_missing", "Payment method missing", "pm_missing"],
|
|
22090
|
-
["payment_failed", "Payment failed", "failed"],
|
|
22091
|
-
["payment_overdue", "Payment overdue", "overdue"],
|
|
22092
|
-
["cancelled", "Cancelled"]
|
|
22093
|
-
],
|
|
22094
|
-
{ fallback: "no_billing" }
|
|
22095
|
-
),
|
|
22096
|
-
dimension2("region", "Country / Region", "geo", [
|
|
22097
|
-
["us_canada", "US / Canada"],
|
|
22098
|
-
["europe", "Europe"],
|
|
22099
|
-
["rest_of_world", "Rest of World", "row"]
|
|
22100
|
-
]),
|
|
22101
|
-
dimension2(
|
|
22102
|
-
"device_type",
|
|
22103
|
-
"Device Type",
|
|
22104
|
-
"dev",
|
|
22105
|
-
[
|
|
22106
|
-
["desktop", "Desktop"],
|
|
22107
|
-
["mobile", "Mobile"],
|
|
22108
|
-
["tablet", "Tablet"],
|
|
22109
|
-
["unknown", "Unknown"]
|
|
22110
|
-
],
|
|
22111
|
-
{ fallback: "unknown" }
|
|
22112
|
-
)
|
|
22113
|
-
];
|
|
22114
|
-
var BY_KEY2 = new Map(
|
|
22115
|
-
BUILTIN_DIMENSIONS2.map((d) => [d.key, d])
|
|
22050
|
+
var { Unrestricted: Unrestricted39 } = DataClassification2;
|
|
22051
|
+
var { Transient: Transient32, Persisted: Persisted24 } = SchemaPersistence2;
|
|
22052
|
+
var { Internal: Internal29, External: External15 } = SchemaExposure2;
|
|
22053
|
+
var PaginationParamsSchema2 = z310.object({
|
|
22054
|
+
page: z310.coerce.number().int().min(1).default(1).meta(Unrestricted39),
|
|
22055
|
+
per_page: z310.coerce.number().int().min(1).max(100).default(25).meta(Unrestricted39)
|
|
22056
|
+
}).meta(
|
|
22057
|
+
{
|
|
22058
|
+
id: "PaginationParams",
|
|
22059
|
+
"x-revturbine-schema-persistence": Transient32,
|
|
22060
|
+
"x-revturbine-schema-exposure": External15
|
|
22061
|
+
}
|
|
22116
22062
|
);
|
|
22117
|
-
|
|
22118
|
-
|
|
22119
|
-
}
|
|
22120
|
-
|
|
22121
|
-
|
|
22122
|
-
|
|
22123
|
-
|
|
22124
|
-
|
|
22125
|
-
|
|
22126
|
-
return `${BUILTIN_SEGMENT_HANDLE_PREFIX2}${key4}.${value}`;
|
|
22127
|
-
}
|
|
22128
|
-
function isReservedSegmentHandle(handle) {
|
|
22129
|
-
return handle.startsWith(BUILTIN_SEGMENT_HANDLE_PREFIX2);
|
|
22130
|
-
}
|
|
22131
|
-
function isBuiltinDimensionValue(key4, value) {
|
|
22132
|
-
const dim = getBuiltinDimension(key4);
|
|
22133
|
-
if (dim.vocabulary === "closed") return dim.values.some((v) => v.value === value);
|
|
22134
|
-
return HANDLE_PATTERN2.test(value) && builtinSegmentHandle2(key4, value).length <= MAX_HANDLE_LENGTH;
|
|
22135
|
-
}
|
|
22136
|
-
function parseBuiltinSegmentHandle(handle) {
|
|
22137
|
-
if (!isReservedSegmentHandle(handle)) return void 0;
|
|
22138
|
-
const rest = handle.slice(BUILTIN_SEGMENT_HANDLE_PREFIX2.length);
|
|
22139
|
-
const dot = rest.indexOf(".");
|
|
22140
|
-
if (dot <= 0) return void 0;
|
|
22141
|
-
const key4 = rest.slice(0, dot);
|
|
22142
|
-
const value = rest.slice(dot + 1);
|
|
22143
|
-
if (!isBuiltinDimensionKey(key4) || !isBuiltinDimensionValue(key4, value)) return void 0;
|
|
22144
|
-
return { key: key4, value };
|
|
22145
|
-
}
|
|
22146
|
-
function isGeneratedBuiltinSegment(segment) {
|
|
22147
|
-
if (typeof segment.handle !== "string") return false;
|
|
22148
|
-
const parsed = parseBuiltinSegmentHandle(segment.handle);
|
|
22149
|
-
if (!parsed) return false;
|
|
22150
|
-
const dim = getBuiltinDimension(parsed.key);
|
|
22151
|
-
if (segment.dimension_id !== dim.dimensionId) return false;
|
|
22152
|
-
if (segment.experiment_handle !== void 0 && segment.experiment_handle !== null) return false;
|
|
22153
|
-
const predicates = segment.predicates;
|
|
22154
|
-
if (!Array.isArray(predicates) || predicates.length !== 1) return false;
|
|
22155
|
-
const [p] = predicates;
|
|
22156
|
-
if (!p || typeof p !== "object") return false;
|
|
22157
|
-
const { field: field2, operator, value } = p;
|
|
22158
|
-
return field2 === dim.traitKey && operator === "eq" && value === parsed.value;
|
|
22159
|
-
}
|
|
22160
|
-
var LEGACY_BY_ID2 = new Map(
|
|
22161
|
-
BUILTIN_DIMENSIONS2.flatMap(
|
|
22162
|
-
(d) => d.values.map((v) => [v.legacyPickerId, builtinSegmentHandle2(d.key, v.value)])
|
|
22163
|
-
)
|
|
22063
|
+
var TimestampFields2 = z310.object({
|
|
22064
|
+
created_at: z310.string().datetime().meta({ ...Unrestricted39, readOnly: true }),
|
|
22065
|
+
updated_at: z310.string().datetime().meta({ ...Unrestricted39, readOnly: true })
|
|
22066
|
+
}).meta(
|
|
22067
|
+
{
|
|
22068
|
+
id: "null",
|
|
22069
|
+
"x-revturbine-schema-persistence": Transient32,
|
|
22070
|
+
"x-revturbine-schema-exposure": External15
|
|
22071
|
+
}
|
|
22164
22072
|
);
|
|
22165
|
-
|
|
22166
|
-
|
|
22167
|
-
}
|
|
22073
|
+
var IdField2 = z310.object({
|
|
22074
|
+
id: z310.string().min(1).meta({ ...Unrestricted39, readOnly: true })
|
|
22075
|
+
}).meta(
|
|
22076
|
+
{
|
|
22077
|
+
id: "null",
|
|
22078
|
+
"x-revturbine-schema-persistence": Transient32,
|
|
22079
|
+
"x-revturbine-schema-exposure": External15
|
|
22080
|
+
}
|
|
22081
|
+
);
|
|
22082
|
+
var TenantIdField2 = z310.object({
|
|
22083
|
+
tenant_id: z310.string().min(1, "tenant_id is required").meta({ ...Unrestricted39, readOnly: true })
|
|
22084
|
+
}).meta(
|
|
22085
|
+
{
|
|
22086
|
+
id: "null",
|
|
22087
|
+
"x-revturbine-schema-persistence": Transient32,
|
|
22088
|
+
"x-revturbine-schema-exposure": Internal29
|
|
22089
|
+
}
|
|
22090
|
+
);
|
|
22091
|
+
var BillingCadenceSchema2 = z310.enum([
|
|
22092
|
+
"monthly",
|
|
22093
|
+
"annual",
|
|
22094
|
+
"quarterly",
|
|
22095
|
+
"one_time",
|
|
22096
|
+
"usage_based"
|
|
22097
|
+
]).meta(
|
|
22098
|
+
{
|
|
22099
|
+
id: "BillingCadence",
|
|
22100
|
+
"x-revturbine-schema-persistence": Transient32,
|
|
22101
|
+
"x-revturbine-schema-exposure": External15
|
|
22102
|
+
}
|
|
22103
|
+
);
|
|
22104
|
+
var COMPONENT_TYPE_VALUES2 = [
|
|
22105
|
+
"banner",
|
|
22106
|
+
"modal",
|
|
22107
|
+
"tooltip",
|
|
22108
|
+
"sidebar",
|
|
22109
|
+
"inline",
|
|
22110
|
+
"toast",
|
|
22111
|
+
"fullscreen",
|
|
22112
|
+
"email",
|
|
22113
|
+
"sms",
|
|
22114
|
+
"push",
|
|
22115
|
+
"in_page",
|
|
22116
|
+
"button",
|
|
22117
|
+
"full_page",
|
|
22118
|
+
"agent",
|
|
22119
|
+
"cli",
|
|
22120
|
+
"custom"
|
|
22121
|
+
];
|
|
22122
|
+
var ComponentTypeSchema2 = z310.enum(COMPONENT_TYPE_VALUES2).meta({ id: "ComponentType", "x-revturbine-schema-persistence": Transient32, "x-revturbine-schema-exposure": External15 });
|
|
22123
|
+
var DEFAULT_TEMPLATE_IDS2 = [
|
|
22124
|
+
"button",
|
|
22125
|
+
"plans_page_ctas",
|
|
22126
|
+
"plans_page_full",
|
|
22127
|
+
"inline_gate_message",
|
|
22128
|
+
"tooltip",
|
|
22129
|
+
"in_page_card",
|
|
22130
|
+
"usage_counter",
|
|
22131
|
+
"credit_counter",
|
|
22132
|
+
"trial_counter",
|
|
22133
|
+
"banner",
|
|
22134
|
+
"modal_optional",
|
|
22135
|
+
"modal_blocking",
|
|
22136
|
+
"toast",
|
|
22137
|
+
"email",
|
|
22138
|
+
"sms",
|
|
22139
|
+
"push",
|
|
22140
|
+
"cli",
|
|
22141
|
+
"agent_connector",
|
|
22142
|
+
"custom_in_app"
|
|
22143
|
+
];
|
|
22144
|
+
var DefaultTemplateIdsSchema2 = z310.enum(DEFAULT_TEMPLATE_IDS2).meta({ id: "DefaultTemplateIds", "x-revturbine-schema-persistence": Transient32, "x-revturbine-schema-exposure": Internal29 });
|
|
22145
|
+
var DEFAULT_TEMPLATE_COMPONENT_TYPES2 = {
|
|
22146
|
+
button: "button",
|
|
22147
|
+
plans_page_ctas: "in_page",
|
|
22148
|
+
plans_page_full: "full_page",
|
|
22149
|
+
inline_gate_message: "inline",
|
|
22150
|
+
tooltip: "tooltip",
|
|
22151
|
+
in_page_card: "in_page",
|
|
22152
|
+
usage_counter: "in_page",
|
|
22153
|
+
credit_counter: "in_page",
|
|
22154
|
+
trial_counter: "in_page",
|
|
22155
|
+
banner: "banner",
|
|
22156
|
+
modal_optional: "modal",
|
|
22157
|
+
modal_blocking: "modal",
|
|
22158
|
+
toast: "toast",
|
|
22159
|
+
email: "email",
|
|
22160
|
+
sms: "sms",
|
|
22161
|
+
push: "push",
|
|
22162
|
+
cli: "cli",
|
|
22163
|
+
agent_connector: "agent",
|
|
22164
|
+
custom_in_app: "custom"
|
|
22165
|
+
};
|
|
22166
|
+
var LEGACY_TEMPLATE_ALIASES2 = Object.freeze({
|
|
22167
|
+
plans_pricing_ctas: "plans_page_ctas",
|
|
22168
|
+
plans_pricing_full: "plans_page_full",
|
|
22169
|
+
credit_balance_counter: "credit_counter",
|
|
22170
|
+
banner_placement: "banner",
|
|
22171
|
+
modal_overlay: "modal_optional",
|
|
22172
|
+
toast_message: "toast",
|
|
22173
|
+
push_notification: "push"
|
|
22174
|
+
});
|
|
22175
|
+
var BUILT_IN_TEMPLATE_COMPONENT_TYPES2 = Object.freeze({
|
|
22176
|
+
...DEFAULT_TEMPLATE_COMPONENT_TYPES2,
|
|
22177
|
+
...Object.fromEntries(
|
|
22178
|
+
Object.entries(LEGACY_TEMPLATE_ALIASES2).map(([legacy, id11]) => [legacy, DEFAULT_TEMPLATE_COMPONENT_TYPES2[id11]])
|
|
22179
|
+
),
|
|
22180
|
+
full_page: "full_page"
|
|
22181
|
+
});
|
|
22182
|
+
var ENTITLEMENT_STATUS_VALUES2 = ["allowed", "limited", "denied"];
|
|
22183
|
+
var PresentationOutcomeSchema2 = z310.enum(["presented", "clicked", "converted", "dismissed", "reminded", "suppressed"]).meta(
|
|
22184
|
+
{ id: "PresentationOutcome", "x-revturbine-schema-persistence": Transient32, "x-revturbine-schema-exposure": External15 }
|
|
22185
|
+
);
|
|
22186
|
+
var EntitlementTypeSchema2 = z310.enum([
|
|
22187
|
+
"feature",
|
|
22188
|
+
"capability_tier",
|
|
22189
|
+
"usage_limit",
|
|
22190
|
+
"price_per_unit",
|
|
22191
|
+
"rate_limit",
|
|
22192
|
+
"credits",
|
|
22193
|
+
"seat"
|
|
22194
|
+
]).meta(
|
|
22195
|
+
{
|
|
22196
|
+
id: "EntitlementType",
|
|
22197
|
+
"x-revturbine-schema-persistence": Transient32,
|
|
22198
|
+
"x-revturbine-schema-exposure": External15
|
|
22199
|
+
}
|
|
22200
|
+
);
|
|
22201
|
+
var CurrencySchema2 = z310.string().regex(/^[a-z]{3}$/, "Currency must be a lowercase ISO 4217 code").default("usd").meta(
|
|
22202
|
+
{
|
|
22203
|
+
id: "Currency",
|
|
22204
|
+
"x-revturbine-schema-persistence": Transient32,
|
|
22205
|
+
"x-revturbine-schema-exposure": External15
|
|
22206
|
+
}
|
|
22207
|
+
);
|
|
22208
|
+
var FeatureFlagValueSchema2 = z310.union([
|
|
22209
|
+
z310.boolean(),
|
|
22210
|
+
z310.number(),
|
|
22211
|
+
z310.string()
|
|
22212
|
+
]).meta(
|
|
22213
|
+
{
|
|
22214
|
+
id: "FeatureFlagValue",
|
|
22215
|
+
"x-revturbine-schema-persistence": Transient32,
|
|
22216
|
+
"x-revturbine-schema-exposure": Internal29
|
|
22217
|
+
}
|
|
22218
|
+
);
|
|
22219
|
+
var NameField2 = z310.string().min(1).max(200);
|
|
22220
|
+
var HandleField2 = z310.string().min(1).max(100);
|
|
22221
|
+
var DescriptionField2 = z310.string().max(500).optional();
|
|
22222
|
+
var MetadataField2 = z310.record(z310.string(), z310.unknown()).default({});
|
|
22223
|
+
var ThresholdPercentField2 = z310.number().int().min(10).max(100).multipleOf(10);
|
|
22224
|
+
var NullableDatetimeField2 = z310.string().datetime().nullable().default(null);
|
|
22225
|
+
var AnchorFields2 = z310.object({
|
|
22226
|
+
environment_id: z310.string().min(1).default("production").meta({ ...Unrestricted39, readOnly: true })
|
|
22227
|
+
}).meta({ id: "null", "x-revturbine-schema-persistence": Transient32, "x-revturbine-schema-exposure": Internal29 });
|
|
22228
|
+
var VersionFields2 = z310.object({
|
|
22229
|
+
// Which playbook version (the review/deploy unit — was `change_set_id`) staged
|
|
22230
|
+
// this ledger row; null once it is the deployed live row.
|
|
22231
|
+
playbook_version_id: z310.string().nullable().default(null).meta(Unrestricted39),
|
|
22232
|
+
is_current: z310.boolean().default(true).meta({ ...Unrestricted39, readOnly: true }),
|
|
22233
|
+
is_deleted: z310.boolean().default(false).meta({ ...Unrestricted39, readOnly: true }),
|
|
22234
|
+
delete_date: z310.string().datetime().nullable().default(null).meta({ ...Unrestricted39, readOnly: true }),
|
|
22235
|
+
// Monotonic version number within a lineage (v1, v2, v3 …); `base_sequence` is
|
|
22236
|
+
// the live sequence this version was forked from (null for the first version),
|
|
22237
|
+
// so a stale draft is detected when live has moved past it.
|
|
22238
|
+
sequence: z310.number().int().min(1).default(1).meta({ ...Unrestricted39, readOnly: true }),
|
|
22239
|
+
base_sequence: z310.number().int().nullable().default(null).meta({ ...Unrestricted39, readOnly: true })
|
|
22240
|
+
}).meta({ id: "null", "x-revturbine-schema-persistence": Transient32, "x-revturbine-schema-exposure": Internal29 });
|
|
22241
|
+
var AnchorBaseSchema2 = IdField2.merge(TimestampFields2).merge(TenantIdField2).merge(AnchorFields2).extend({
|
|
22242
|
+
handle: HandleField2.meta({ ...Unrestricted39, readOnly: true }),
|
|
22243
|
+
active: z310.boolean().default(true).meta({ ...Unrestricted39, readOnly: true })
|
|
22244
|
+
});
|
|
22245
|
+
function makeAnchor2(id11) {
|
|
22246
|
+
return AnchorBaseSchema2.meta({
|
|
22247
|
+
id: id11,
|
|
22248
|
+
"x-revturbine-schema-persistence": Persisted24,
|
|
22249
|
+
"x-revturbine-schema-exposure": Internal29
|
|
22250
|
+
});
|
|
22251
|
+
}
|
|
22252
|
+
var SeveritySchema22 = z310.enum(["info", "warning", "critical"]).meta({ id: "Severity", "x-revturbine-schema-persistence": Transient32, "x-revturbine-schema-exposure": Internal29 });
|
|
22253
|
+
var CtaActionTypeSchema2 = z310.enum([
|
|
22254
|
+
"open_checkout",
|
|
22255
|
+
"view_plans",
|
|
22256
|
+
"book_demo",
|
|
22257
|
+
"contact_sales",
|
|
22258
|
+
"complete_onboarding",
|
|
22259
|
+
"invite_teammate",
|
|
22260
|
+
"refer_friend",
|
|
22261
|
+
"verify_work_email",
|
|
22262
|
+
"update_payment_method",
|
|
22263
|
+
"enable_auto_renewal",
|
|
22264
|
+
"manage_subscription",
|
|
22265
|
+
"switch_billing_period",
|
|
22266
|
+
"extend_trial",
|
|
22267
|
+
"open_rt_placement",
|
|
22268
|
+
"dismiss",
|
|
22269
|
+
"snooze",
|
|
22270
|
+
"custom"
|
|
22271
|
+
]).meta({ id: "CtaActionType", "x-revturbine-schema-persistence": Transient32, "x-revturbine-schema-exposure": External15 });
|
|
22272
|
+
var ObjectiveField2 = HandleField2.optional();
|
|
22273
|
+
function hasCreditResetPeriod2(fields) {
|
|
22274
|
+
return fields.reset_period !== void 0 && fields.reset_period !== null;
|
|
22275
|
+
}
|
|
22276
|
+
function allowancePeriod2(kind, fields, billingPeriod) {
|
|
22277
|
+
if (kind === "seat") return "seat";
|
|
22278
|
+
const raw = kind === "credits" ? fields.reset_period : fields.period_scope;
|
|
22279
|
+
if (raw === "billing_period" || raw === "per_billing_period") {
|
|
22280
|
+
if (billingPeriod === "monthly") return "month";
|
|
22281
|
+
if (billingPeriod === "annual") return "year";
|
|
22282
|
+
return void 0;
|
|
22283
|
+
}
|
|
22284
|
+
if (typeof raw !== "string" || raw === "") return void 0;
|
|
22285
|
+
if (raw === "per_6_hours" || raw === "six_hours") return "six_hours";
|
|
22286
|
+
return raw.startsWith("per_") ? raw.slice(4) : raw;
|
|
22287
|
+
}
|
|
22288
|
+
function assertCompatibleAllowances2(a, b, aBillingPeriod, bBillingPeriod) {
|
|
22289
|
+
const aPeriod = allowancePeriod2(a.kind, a.fields, aBillingPeriod);
|
|
22290
|
+
const bPeriod = allowancePeriod2(b.kind, b.fields, bBillingPeriod);
|
|
22291
|
+
if (a.kind !== b.kind || aPeriod === void 0 || aPeriod !== bPeriod || (a.fields.allocation ?? "account") !== (b.fields.allocation ?? "account") || (a.fields.instance ?? "") !== (b.fields.instance ?? "") || (a.fields.seat_type_id ?? "") !== (b.fields.seat_type_id ?? "")) {
|
|
22292
|
+
throw new Error(`Incompatible purchased allowances: ${a.ruleId} and ${b.ruleId} require matching periods and scopes`);
|
|
22293
|
+
}
|
|
22294
|
+
}
|
|
22295
|
+
var BUILTIN_SEGMENT_HANDLE_PREFIX2 = "rt.";
|
|
22296
|
+
var BUILTIN_TRAIT_KEY_PREFIX2 = "rt_";
|
|
22297
|
+
var MAX_HANDLE_LENGTH = 100;
|
|
22298
|
+
function dimension2(key4, name, legacyAbbr, values, opts = {}) {
|
|
22299
|
+
const legacyPrefix = `seg:${legacyAbbr}:`;
|
|
22300
|
+
return {
|
|
22301
|
+
key: key4,
|
|
22302
|
+
name,
|
|
22303
|
+
traitKey: `${BUILTIN_TRAIT_KEY_PREFIX2}${key4}`,
|
|
22304
|
+
dimensionId: `${BUILTIN_SEGMENT_HANDLE_PREFIX2}${key4}`,
|
|
22305
|
+
vocabulary: opts.vocabulary ?? "closed",
|
|
22306
|
+
values: values.map(([value, valueName, legacyValue]) => ({
|
|
22307
|
+
value,
|
|
22308
|
+
name: valueName,
|
|
22309
|
+
legacyPickerId: `${legacyPrefix}${legacyValue ?? value}`
|
|
22310
|
+
})),
|
|
22311
|
+
...opts.fallback !== void 0 ? { fallback: opts.fallback } : {},
|
|
22312
|
+
legacyPrefix
|
|
22313
|
+
};
|
|
22314
|
+
}
|
|
22315
|
+
var BUILTIN_DIMENSIONS2 = [
|
|
22316
|
+
dimension2("registration_state", "Registration State", "reg", [
|
|
22317
|
+
["unregistered", "Unregistered"],
|
|
22318
|
+
["registered", "Registered"]
|
|
22319
|
+
]),
|
|
22320
|
+
dimension2(
|
|
22321
|
+
"activity_level",
|
|
22322
|
+
"Activity State",
|
|
22323
|
+
"act",
|
|
22324
|
+
[
|
|
22325
|
+
["new", "New"],
|
|
22326
|
+
["high", "High Activity"],
|
|
22327
|
+
["medium", "Medium Activity"],
|
|
22328
|
+
["low", "Low Activity"],
|
|
22329
|
+
["inactive", "Inactive"]
|
|
22330
|
+
],
|
|
22331
|
+
{ fallback: "new" }
|
|
22332
|
+
),
|
|
22333
|
+
dimension2(
|
|
22334
|
+
"subscription_state",
|
|
22335
|
+
"Subscription State",
|
|
22336
|
+
"sub",
|
|
22337
|
+
[
|
|
22338
|
+
["none", "None"],
|
|
22339
|
+
["trial", "Trial"],
|
|
22340
|
+
["paid", "Paid"],
|
|
22341
|
+
["cancelled", "Cancelled"]
|
|
22342
|
+
],
|
|
22343
|
+
{ fallback: "none" }
|
|
22344
|
+
),
|
|
22345
|
+
dimension2(
|
|
22346
|
+
"trial_type",
|
|
22347
|
+
"Trial Type",
|
|
22348
|
+
"trial",
|
|
22349
|
+
[
|
|
22350
|
+
["none", "Not in trial"],
|
|
22351
|
+
["free_trial", "Free trial", "free"],
|
|
22352
|
+
["reverse_trial", "Reverse trial", "reverse"]
|
|
22353
|
+
],
|
|
22354
|
+
{ fallback: "none" }
|
|
22355
|
+
),
|
|
22356
|
+
dimension2("seat_type", "Seat Type", "seat", [], { vocabulary: "seat_type" }),
|
|
22357
|
+
dimension2("buyer_role", "Buyer Role", "role", [
|
|
22358
|
+
["buyer", "Buyer"],
|
|
22359
|
+
["non_buyer", "Non-buyer"]
|
|
22360
|
+
]),
|
|
22361
|
+
dimension2(
|
|
22362
|
+
"email_type",
|
|
22363
|
+
"Email Type",
|
|
22364
|
+
"email",
|
|
22365
|
+
[
|
|
22366
|
+
["business", "Business email"],
|
|
22367
|
+
["personal", "Personal email"],
|
|
22368
|
+
["unknown", "Unknown"]
|
|
22369
|
+
],
|
|
22370
|
+
{ fallback: "unknown" }
|
|
22371
|
+
),
|
|
22372
|
+
dimension2(
|
|
22373
|
+
"billing_health",
|
|
22374
|
+
"Billing Health",
|
|
22375
|
+
"bill",
|
|
22376
|
+
[
|
|
22377
|
+
["no_billing", "No billing", "none"],
|
|
22378
|
+
["good_standing", "Good standing", "good"],
|
|
22379
|
+
["trial_payment_method_attached", "Trial \u2014 payment method attached", "trial_pm"],
|
|
22380
|
+
["payment_method_missing", "Payment method missing", "pm_missing"],
|
|
22381
|
+
["payment_failed", "Payment failed", "failed"],
|
|
22382
|
+
["payment_overdue", "Payment overdue", "overdue"],
|
|
22383
|
+
["cancelled", "Cancelled"]
|
|
22384
|
+
],
|
|
22385
|
+
{ fallback: "no_billing" }
|
|
22386
|
+
),
|
|
22387
|
+
dimension2("region", "Country / Region", "geo", [
|
|
22388
|
+
["us_canada", "US / Canada"],
|
|
22389
|
+
["europe", "Europe"],
|
|
22390
|
+
["rest_of_world", "Rest of World", "row"]
|
|
22391
|
+
]),
|
|
22392
|
+
dimension2(
|
|
22393
|
+
"device_type",
|
|
22394
|
+
"Device Type",
|
|
22395
|
+
"dev",
|
|
22396
|
+
[
|
|
22397
|
+
["desktop", "Desktop"],
|
|
22398
|
+
["mobile", "Mobile"],
|
|
22399
|
+
["tablet", "Tablet"],
|
|
22400
|
+
["unknown", "Unknown"]
|
|
22401
|
+
],
|
|
22402
|
+
{ fallback: "unknown" }
|
|
22403
|
+
)
|
|
22404
|
+
];
|
|
22405
|
+
var BY_KEY2 = new Map(
|
|
22406
|
+
BUILTIN_DIMENSIONS2.map((d) => [d.key, d])
|
|
22407
|
+
);
|
|
22408
|
+
function isBuiltinDimensionKey(key4) {
|
|
22409
|
+
return BY_KEY2.has(key4);
|
|
22410
|
+
}
|
|
22411
|
+
function getBuiltinDimension(key4) {
|
|
22412
|
+
const found = BY_KEY2.get(key4);
|
|
22413
|
+
if (!found) throw new Error(`Unknown built-in dimension '${key4}'`);
|
|
22414
|
+
return found;
|
|
22415
|
+
}
|
|
22416
|
+
function builtinSegmentHandle2(key4, value) {
|
|
22417
|
+
return `${BUILTIN_SEGMENT_HANDLE_PREFIX2}${key4}.${value}`;
|
|
22418
|
+
}
|
|
22419
|
+
function isReservedSegmentHandle(handle) {
|
|
22420
|
+
return handle.startsWith(BUILTIN_SEGMENT_HANDLE_PREFIX2);
|
|
22421
|
+
}
|
|
22422
|
+
function isBuiltinDimensionValue(key4, value) {
|
|
22423
|
+
const dim = getBuiltinDimension(key4);
|
|
22424
|
+
if (dim.vocabulary === "closed") return dim.values.some((v) => v.value === value);
|
|
22425
|
+
return HANDLE_PATTERN2.test(value) && builtinSegmentHandle2(key4, value).length <= MAX_HANDLE_LENGTH;
|
|
22426
|
+
}
|
|
22427
|
+
function parseBuiltinSegmentHandle(handle) {
|
|
22428
|
+
if (!isReservedSegmentHandle(handle)) return void 0;
|
|
22429
|
+
const rest = handle.slice(BUILTIN_SEGMENT_HANDLE_PREFIX2.length);
|
|
22430
|
+
const dot = rest.indexOf(".");
|
|
22431
|
+
if (dot <= 0) return void 0;
|
|
22432
|
+
const key4 = rest.slice(0, dot);
|
|
22433
|
+
const value = rest.slice(dot + 1);
|
|
22434
|
+
if (!isBuiltinDimensionKey(key4) || !isBuiltinDimensionValue(key4, value)) return void 0;
|
|
22435
|
+
return { key: key4, value };
|
|
22436
|
+
}
|
|
22437
|
+
function isGeneratedBuiltinSegment(segment) {
|
|
22438
|
+
if (typeof segment.handle !== "string") return false;
|
|
22439
|
+
const parsed = parseBuiltinSegmentHandle(segment.handle);
|
|
22440
|
+
if (!parsed) return false;
|
|
22441
|
+
const dim = getBuiltinDimension(parsed.key);
|
|
22442
|
+
if (segment.dimension_id !== dim.dimensionId) return false;
|
|
22443
|
+
if (segment.experiment_handle !== void 0 && segment.experiment_handle !== null) return false;
|
|
22444
|
+
const predicates = segment.predicates;
|
|
22445
|
+
if (!Array.isArray(predicates) || predicates.length !== 1) return false;
|
|
22446
|
+
const [p] = predicates;
|
|
22447
|
+
if (!p || typeof p !== "object") return false;
|
|
22448
|
+
const { field: field2, operator, value } = p;
|
|
22449
|
+
return field2 === dim.traitKey && operator === "eq" && value === parsed.value;
|
|
22450
|
+
}
|
|
22451
|
+
var LEGACY_BY_ID2 = new Map(
|
|
22452
|
+
BUILTIN_DIMENSIONS2.flatMap(
|
|
22453
|
+
(d) => d.values.map((v) => [v.legacyPickerId, builtinSegmentHandle2(d.key, v.value)])
|
|
22454
|
+
)
|
|
22455
|
+
);
|
|
22456
|
+
function identity2(row) {
|
|
22457
|
+
return String(row.unique_handle ?? row.handle ?? row.id ?? "");
|
|
22458
|
+
}
|
|
22168
22459
|
function matchesIdentity2(row, key4) {
|
|
22169
22460
|
return typeof key4 === "string" && [row.unique_handle, row.handle, row.id].includes(key4);
|
|
22170
22461
|
}
|
|
@@ -22289,6 +22580,7 @@ function runSemanticRules(graph, opts = {}) {
|
|
|
22289
22580
|
...checkLimitRuleEnforcement(graph),
|
|
22290
22581
|
...checkPublicVariationCollisions(graph),
|
|
22291
22582
|
...checkPayloadCtaOverflow(graph),
|
|
22583
|
+
...checkPayloadTemplateRefs(graph),
|
|
22292
22584
|
...checkPlacementAuthoring(graph),
|
|
22293
22585
|
...checkTrialRuleWidestAudience(graph),
|
|
22294
22586
|
...checkSegmentExperimentRefs(graph),
|
|
@@ -22752,6 +23044,42 @@ function checkPayloadCtaOverflow(graph) {
|
|
|
22752
23044
|
}
|
|
22753
23045
|
return findings;
|
|
22754
23046
|
}
|
|
23047
|
+
function checkPayloadTemplateRefs(graph) {
|
|
23048
|
+
const known = new Set(Object.keys(BUILT_IN_TEMPLATE_COMPONENT_TYPES2));
|
|
23049
|
+
for (const template of graph.surface_templates ?? []) {
|
|
23050
|
+
if (typeof template.id !== "string" || !template.id) return [];
|
|
23051
|
+
known.add(template.id);
|
|
23052
|
+
}
|
|
23053
|
+
const findings = [];
|
|
23054
|
+
const check = (payloadId, surfaces, path3) => {
|
|
23055
|
+
if (!Array.isArray(surfaces)) return;
|
|
23056
|
+
surfaces.forEach((surface, index) => {
|
|
23057
|
+
if (!isRecord3(surface) || typeof surface.template_id !== "string") return;
|
|
23058
|
+
if (known.has(surface.template_id)) return;
|
|
23059
|
+
findings.push(finding("VAL-PLC-11", {
|
|
23060
|
+
object_type: "placement_payload",
|
|
23061
|
+
object_id: payloadId,
|
|
23062
|
+
field: "template_id",
|
|
23063
|
+
path: [...path3, "surfaces", index, "template_id"],
|
|
23064
|
+
studio: "placements"
|
|
23065
|
+
}, {
|
|
23066
|
+
message: `Payload '${payloadId}' uses surface template '${surface.template_id}', which is neither built in nor defined in surface_templates. SDKs skip this payload.`,
|
|
23067
|
+
detail: "Use a built-in template id, or add a surface_templates entry with this id and a surface_type."
|
|
23068
|
+
}));
|
|
23069
|
+
});
|
|
23070
|
+
};
|
|
23071
|
+
(graph.placements ?? []).forEach((placement, placementIndex) => {
|
|
23072
|
+
const payloads = Array.isArray(placement.payloads) ? placement.payloads : [];
|
|
23073
|
+
payloads.forEach((payload, payloadIndex) => {
|
|
23074
|
+
if (!isRecord3(payload)) return;
|
|
23075
|
+
check(String(payload.id ?? placement.id ?? ""), payload.surfaces, ["placements", placementIndex, "payloads", payloadIndex]);
|
|
23076
|
+
});
|
|
23077
|
+
});
|
|
23078
|
+
(graph.placement_payloads ?? []).forEach((payload, index) => {
|
|
23079
|
+
check(String(payload.payload_id ?? payload.id ?? ""), payload.surfaces, ["placement_payloads", index]);
|
|
23080
|
+
});
|
|
23081
|
+
return findings;
|
|
23082
|
+
}
|
|
22755
23083
|
function checkTrialRuleWidestAudience(graph) {
|
|
22756
23084
|
const findings = [];
|
|
22757
23085
|
for (const rule of graph.free_trial_rules ?? []) {
|
|
@@ -23022,374 +23350,112 @@ function checkPublicVariationCollisions(graph) {
|
|
|
23022
23350
|
...collectPublicCollisions(graph.addon_variations, "addon_variation", "addon_id")
|
|
23023
23351
|
];
|
|
23024
23352
|
}
|
|
23025
|
-
function collectPublicCollisions(rows, objectType, parentField) {
|
|
23026
|
-
if (!rows?.length) return [];
|
|
23027
|
-
const parentHandleField = parentField === "plan_id" ? "plan_handle" : "addon_handle";
|
|
23028
|
-
const publicByTuple = /* @__PURE__ */ new Map();
|
|
23029
|
-
for (const row of rows) {
|
|
23030
|
-
if (row.is_current === false) continue;
|
|
23031
|
-
if (String(row.visibility ?? "public") !== "public") continue;
|
|
23032
|
-
const parentRef = row[parentField] ?? row[parentHandleField];
|
|
23033
|
-
if (parentRef == null || String(parentRef) === "") continue;
|
|
23034
|
-
const segmentRef = row.segment_id ?? row.segment_handle;
|
|
23035
|
-
const tenant = String(row.tenant_id ?? "");
|
|
23036
|
-
const parent2 = String(parentRef);
|
|
23037
|
-
const period = String(row.billing_period ?? "");
|
|
23038
|
-
const segment = segmentRef == null ? "_default" : String(segmentRef);
|
|
23039
|
-
const key4 = `${tenant} ${parent2} ${period} ${segment}`;
|
|
23040
|
-
const id11 = String(row.handle ?? row.id ?? "");
|
|
23041
|
-
const bucket = publicByTuple.get(key4);
|
|
23042
|
-
if (bucket) bucket.ids.push(id11);
|
|
23043
|
-
else publicByTuple.set(key4, { ids: [id11], parent: parent2, period, segment });
|
|
23044
|
-
}
|
|
23045
|
-
const findings = [];
|
|
23046
|
-
for (const bucket of publicByTuple.values()) {
|
|
23047
|
-
if (bucket.ids.length < 2) continue;
|
|
23048
|
-
const allIds = [...bucket.ids].sort();
|
|
23049
|
-
const segmentLabel = bucket.segment === "_default" ? "no segment" : `segment ${bucket.segment}`;
|
|
23050
|
-
const parentLabel = parentField === "plan_id" ? "plan" : "add-on";
|
|
23051
|
-
for (const id11 of bucket.ids) {
|
|
23052
|
-
findings.push(
|
|
23053
|
-
finding(
|
|
23054
|
-
"VAL-PLN-06",
|
|
23055
|
-
{
|
|
23056
|
-
object_type: objectType,
|
|
23057
|
-
object_id: id11,
|
|
23058
|
-
field: "visibility",
|
|
23059
|
-
studio: "plans-entitlements"
|
|
23060
|
-
},
|
|
23061
|
-
{
|
|
23062
|
-
message: `Variation '${id11}' is one of ${bucket.ids.length} marked Public for the same ${parentLabel}, billing period '${bucket.period}', and ${segmentLabel} \u2014 only one may be Public.`,
|
|
23063
|
-
detail: `Set all but one of [${allIds.join(", ")}] to Unlisted or Legacy before deploying.`
|
|
23064
|
-
}
|
|
23065
|
-
)
|
|
23066
|
-
);
|
|
23067
|
-
}
|
|
23068
|
-
}
|
|
23069
|
-
return findings;
|
|
23070
|
-
}
|
|
23071
|
-
function fieldLabel(path3) {
|
|
23072
|
-
if (!path3 || path3.length === 0) return "This value";
|
|
23073
|
-
return String(path3[path3.length - 1]);
|
|
23074
|
-
}
|
|
23075
|
-
function messageForZodIssue(issue) {
|
|
23076
|
-
const field2 = fieldLabel(issue.path);
|
|
23077
|
-
switch (issue.code) {
|
|
23078
|
-
case "invalid_type":
|
|
23079
|
-
return issue.input === void 0 ? `${field2} is required.` : `${field2} must be a ${issue.expected ?? "valid value"}.`;
|
|
23080
|
-
case "invalid_value": {
|
|
23081
|
-
const values = (issue.values ?? []).filter(
|
|
23082
|
-
(v) => ["string", "number", "boolean"].includes(typeof v)
|
|
23083
|
-
);
|
|
23084
|
-
return values.length > 0 ? `${field2} must be one of: ${values.map((v) => `'${String(v)}'`).join(", ")}.` : `${field2} must be one of the allowed values.`;
|
|
23085
|
-
}
|
|
23086
|
-
case "invalid_format":
|
|
23087
|
-
return `${field2} isn't in a valid format.`;
|
|
23088
|
-
case "too_small":
|
|
23089
|
-
return `${field2} is too small.`;
|
|
23090
|
-
case "too_big":
|
|
23091
|
-
return `${field2} is too large.`;
|
|
23092
|
-
case "unrecognized_keys":
|
|
23093
|
-
return `${field2} isn't a recognized setting.`;
|
|
23094
|
-
default:
|
|
23095
|
-
return issue.message ?? `${field2} is invalid.`;
|
|
23096
|
-
}
|
|
23097
|
-
}
|
|
23098
|
-
function targetRefForIssue(issue, basePath) {
|
|
23099
|
-
const path3 = [...basePath, ...issue.path ?? []].map(
|
|
23100
|
-
(seg2) => typeof seg2 === "number" ? seg2 : String(seg2)
|
|
23101
|
-
);
|
|
23102
|
-
return { path: path3 };
|
|
23103
|
-
}
|
|
23104
|
-
function zodErrorToFindings(error2, opts = {}) {
|
|
23105
|
-
const basePath = opts.basePath ?? [];
|
|
23106
|
-
return error2.issues.map((issue) => ({
|
|
23107
|
-
code: issue.code ?? "invalid",
|
|
23108
|
-
severity: "error_draft",
|
|
23109
|
-
targetRef: targetRefForIssue(issue, basePath),
|
|
23110
|
-
message: messageForZodIssue(issue),
|
|
23111
|
-
...opts.specRef ? { specRef: opts.specRef } : {}
|
|
23112
|
-
}));
|
|
23113
|
-
}
|
|
23114
|
-
function spotlights(finding2, focus) {
|
|
23115
|
-
if (!focus) return false;
|
|
23116
|
-
const { object_type, object_id } = finding2.targetRef;
|
|
23117
|
-
if (focus.object_id != null && object_id !== focus.object_id) return false;
|
|
23118
|
-
if (focus.object_type != null && object_type !== focus.object_type) return false;
|
|
23119
|
-
return focus.object_id != null || focus.object_type != null;
|
|
23120
|
-
}
|
|
23121
|
-
function evaluate(graph, opts = {}) {
|
|
23122
|
-
const findings = [];
|
|
23123
|
-
if (opts.structuralErrors) {
|
|
23124
|
-
const errors2 = Array.isArray(opts.structuralErrors) ? opts.structuralErrors : [opts.structuralErrors];
|
|
23125
|
-
for (const error2 of errors2) findings.push(...zodErrorToFindings(error2));
|
|
23126
|
-
}
|
|
23127
|
-
findings.push(...runSemanticRules(graph, { knownMetricIds: opts.knownMetricIds }));
|
|
23128
|
-
if (!opts.focus) return findings;
|
|
23129
|
-
return findings.map((f) => spotlights(f, opts.focus) ? { ...f, spotlight: true } : f);
|
|
23130
|
-
}
|
|
23131
|
-
var SchemaPersistence2 = {
|
|
23132
|
-
Persisted: "persisted",
|
|
23133
|
-
Transient: "transient"
|
|
23134
|
-
};
|
|
23135
|
-
var SchemaExposure2 = {
|
|
23136
|
-
Internal: "internal",
|
|
23137
|
-
External: "external"
|
|
23138
|
-
};
|
|
23139
|
-
var DataClassification2 = {
|
|
23140
|
-
Pii: { "x-revturbine-data-classification": "pii" },
|
|
23141
|
-
Financial: { "x-revturbine-data-classification": "financial" },
|
|
23142
|
-
Unrestricted: { "x-revturbine-data-classification": "unrestricted" },
|
|
23143
|
-
/**
|
|
23144
|
-
* Machine-generated evaluation exhaust — supersession records, entitlement
|
|
23145
|
-
* grants, placement decision traces. Carries no personal or financial data
|
|
23146
|
-
* itself, but describes what the engine decided about a user, so it is not
|
|
23147
|
-
* `Unrestricted` either. Applied at the MODEL level (plan 182 REQ-7); it was
|
|
23148
|
-
* already in use as a raw string literal on four schemas before being
|
|
23149
|
-
* declared here, which left `DataClassificationValue` unable to represent it.
|
|
23150
|
-
*/
|
|
23151
|
-
Operational: { "x-revturbine-data-classification": "operational" }
|
|
23152
|
-
};
|
|
23153
|
-
var SCHEMA_EXPOSURE_META_KEY2 = "x-revturbine-schema-exposure";
|
|
23154
|
-
var READ_ONLY_META_KEY2 = "readOnly";
|
|
23155
|
-
var DECISION_ONLY_META_KEY2 = "x-revturbine-decision-only";
|
|
23156
|
-
var DecisionOnly2 = { [DECISION_ONLY_META_KEY2]: true };
|
|
23157
|
-
var ClientSafe2 = { [SCHEMA_EXPOSURE_META_KEY2]: SchemaExposure2.External };
|
|
23158
|
-
var ServerOnly2 = { [SCHEMA_EXPOSURE_META_KEY2]: SchemaExposure2.Internal };
|
|
23159
|
-
function toWritableSchema2(schema) {
|
|
23160
|
-
const writableShape = {};
|
|
23161
|
-
for (const [fieldName, fieldSchema] of Object.entries(schema.shape)) {
|
|
23162
|
-
if (typeof fieldSchema !== "object" || fieldSchema === null) {
|
|
23163
|
-
continue;
|
|
23164
|
-
}
|
|
23165
|
-
const isReadOnly = fieldSchema.meta()?.[READ_ONLY_META_KEY2] === true;
|
|
23166
|
-
if (!isReadOnly) {
|
|
23167
|
-
writableShape[fieldName] = fieldSchema;
|
|
23168
|
-
}
|
|
23169
|
-
}
|
|
23170
|
-
return z210.object(writableShape);
|
|
23171
|
-
}
|
|
23172
|
-
function toCreateSchema2(schema) {
|
|
23173
|
-
const writable = toWritableSchema2(schema);
|
|
23174
|
-
const handleField = writable.shape["handle"];
|
|
23175
|
-
if (handleField && typeof handleField.regex === "function") {
|
|
23176
|
-
return writable.extend({ handle: handleField.regex(HANDLE_PATTERN2) });
|
|
23177
|
-
}
|
|
23178
|
-
return writable;
|
|
23179
|
-
}
|
|
23180
|
-
var { Unrestricted: Unrestricted39 } = DataClassification2;
|
|
23181
|
-
var { Transient: Transient32, Persisted: Persisted24 } = SchemaPersistence2;
|
|
23182
|
-
var { Internal: Internal29, External: External15 } = SchemaExposure2;
|
|
23183
|
-
var PaginationParamsSchema2 = z310.object({
|
|
23184
|
-
page: z310.coerce.number().int().min(1).default(1).meta(Unrestricted39),
|
|
23185
|
-
per_page: z310.coerce.number().int().min(1).max(100).default(25).meta(Unrestricted39)
|
|
23186
|
-
}).meta(
|
|
23187
|
-
{
|
|
23188
|
-
id: "PaginationParams",
|
|
23189
|
-
"x-revturbine-schema-persistence": Transient32,
|
|
23190
|
-
"x-revturbine-schema-exposure": External15
|
|
23191
|
-
}
|
|
23192
|
-
);
|
|
23193
|
-
var TimestampFields2 = z310.object({
|
|
23194
|
-
created_at: z310.string().datetime().meta({ ...Unrestricted39, readOnly: true }),
|
|
23195
|
-
updated_at: z310.string().datetime().meta({ ...Unrestricted39, readOnly: true })
|
|
23196
|
-
}).meta(
|
|
23197
|
-
{
|
|
23198
|
-
id: "null",
|
|
23199
|
-
"x-revturbine-schema-persistence": Transient32,
|
|
23200
|
-
"x-revturbine-schema-exposure": External15
|
|
23201
|
-
}
|
|
23202
|
-
);
|
|
23203
|
-
var IdField2 = z310.object({
|
|
23204
|
-
id: z310.string().min(1).meta({ ...Unrestricted39, readOnly: true })
|
|
23205
|
-
}).meta(
|
|
23206
|
-
{
|
|
23207
|
-
id: "null",
|
|
23208
|
-
"x-revturbine-schema-persistence": Transient32,
|
|
23209
|
-
"x-revturbine-schema-exposure": External15
|
|
23210
|
-
}
|
|
23211
|
-
);
|
|
23212
|
-
var TenantIdField2 = z310.object({
|
|
23213
|
-
tenant_id: z310.string().min(1, "tenant_id is required").meta({ ...Unrestricted39, readOnly: true })
|
|
23214
|
-
}).meta(
|
|
23215
|
-
{
|
|
23216
|
-
id: "null",
|
|
23217
|
-
"x-revturbine-schema-persistence": Transient32,
|
|
23218
|
-
"x-revturbine-schema-exposure": Internal29
|
|
23219
|
-
}
|
|
23220
|
-
);
|
|
23221
|
-
var BillingCadenceSchema2 = z310.enum([
|
|
23222
|
-
"monthly",
|
|
23223
|
-
"annual",
|
|
23224
|
-
"quarterly",
|
|
23225
|
-
"one_time",
|
|
23226
|
-
"usage_based"
|
|
23227
|
-
]).meta(
|
|
23228
|
-
{
|
|
23229
|
-
id: "BillingCadence",
|
|
23230
|
-
"x-revturbine-schema-persistence": Transient32,
|
|
23231
|
-
"x-revturbine-schema-exposure": External15
|
|
23353
|
+
function collectPublicCollisions(rows, objectType, parentField) {
|
|
23354
|
+
if (!rows?.length) return [];
|
|
23355
|
+
const parentHandleField = parentField === "plan_id" ? "plan_handle" : "addon_handle";
|
|
23356
|
+
const publicByTuple = /* @__PURE__ */ new Map();
|
|
23357
|
+
for (const row of rows) {
|
|
23358
|
+
if (row.is_current === false) continue;
|
|
23359
|
+
if (String(row.visibility ?? "public") !== "public") continue;
|
|
23360
|
+
const parentRef = row[parentField] ?? row[parentHandleField];
|
|
23361
|
+
if (parentRef == null || String(parentRef) === "") continue;
|
|
23362
|
+
const segmentRef = row.segment_id ?? row.segment_handle;
|
|
23363
|
+
const tenant = String(row.tenant_id ?? "");
|
|
23364
|
+
const parent2 = String(parentRef);
|
|
23365
|
+
const period = String(row.billing_period ?? "");
|
|
23366
|
+
const segment = segmentRef == null ? "_default" : String(segmentRef);
|
|
23367
|
+
const key4 = `${tenant} ${parent2} ${period} ${segment}`;
|
|
23368
|
+
const id11 = String(row.handle ?? row.id ?? "");
|
|
23369
|
+
const bucket = publicByTuple.get(key4);
|
|
23370
|
+
if (bucket) bucket.ids.push(id11);
|
|
23371
|
+
else publicByTuple.set(key4, { ids: [id11], parent: parent2, period, segment });
|
|
23232
23372
|
}
|
|
23233
|
-
|
|
23234
|
-
|
|
23235
|
-
|
|
23236
|
-
|
|
23237
|
-
|
|
23238
|
-
|
|
23239
|
-
|
|
23240
|
-
|
|
23241
|
-
|
|
23242
|
-
|
|
23243
|
-
|
|
23244
|
-
|
|
23245
|
-
|
|
23246
|
-
|
|
23247
|
-
|
|
23248
|
-
|
|
23249
|
-
|
|
23250
|
-
|
|
23251
|
-
]
|
|
23252
|
-
|
|
23253
|
-
|
|
23254
|
-
|
|
23255
|
-
|
|
23256
|
-
"plans_page_full",
|
|
23257
|
-
"inline_gate_message",
|
|
23258
|
-
"tooltip",
|
|
23259
|
-
"in_page_card",
|
|
23260
|
-
"usage_counter",
|
|
23261
|
-
"credit_counter",
|
|
23262
|
-
"trial_counter",
|
|
23263
|
-
"banner",
|
|
23264
|
-
"modal_optional",
|
|
23265
|
-
"modal_blocking",
|
|
23266
|
-
"toast",
|
|
23267
|
-
"email",
|
|
23268
|
-
"sms",
|
|
23269
|
-
"push",
|
|
23270
|
-
"cli",
|
|
23271
|
-
"agent_connector",
|
|
23272
|
-
"custom_in_app"
|
|
23273
|
-
];
|
|
23274
|
-
var DefaultTemplateIdsSchema2 = z310.enum(DEFAULT_TEMPLATE_IDS2).meta({ id: "DefaultTemplateIds", "x-revturbine-schema-persistence": Transient32, "x-revturbine-schema-exposure": Internal29 });
|
|
23275
|
-
var DEFAULT_TEMPLATE_COMPONENT_TYPES2 = {
|
|
23276
|
-
button: "button",
|
|
23277
|
-
plans_page_ctas: "in_page",
|
|
23278
|
-
plans_page_full: "full_page",
|
|
23279
|
-
inline_gate_message: "inline",
|
|
23280
|
-
tooltip: "tooltip",
|
|
23281
|
-
in_page_card: "in_page",
|
|
23282
|
-
usage_counter: "in_page",
|
|
23283
|
-
credit_counter: "in_page",
|
|
23284
|
-
trial_counter: "in_page",
|
|
23285
|
-
banner: "banner",
|
|
23286
|
-
modal_optional: "modal",
|
|
23287
|
-
modal_blocking: "modal",
|
|
23288
|
-
toast: "toast",
|
|
23289
|
-
email: "email",
|
|
23290
|
-
sms: "sms",
|
|
23291
|
-
push: "push",
|
|
23292
|
-
cli: "cli",
|
|
23293
|
-
agent_connector: "agent",
|
|
23294
|
-
custom_in_app: "custom"
|
|
23295
|
-
};
|
|
23296
|
-
var BUILT_IN_TEMPLATE_COMPONENT_TYPES2 = Object.freeze({
|
|
23297
|
-
...DEFAULT_TEMPLATE_COMPONENT_TYPES2,
|
|
23298
|
-
modal_overlay: "modal",
|
|
23299
|
-
banner_placement: "banner",
|
|
23300
|
-
full_page: "full_page"
|
|
23301
|
-
});
|
|
23302
|
-
var ENTITLEMENT_STATUS_VALUES2 = ["allowed", "limited", "denied"];
|
|
23303
|
-
var PresentationOutcomeSchema2 = z310.enum(["presented", "clicked", "converted", "dismissed", "reminded", "suppressed"]).meta(
|
|
23304
|
-
{ id: "PresentationOutcome", "x-revturbine-schema-persistence": Transient32, "x-revturbine-schema-exposure": External15 }
|
|
23305
|
-
);
|
|
23306
|
-
var EntitlementTypeSchema2 = z310.enum([
|
|
23307
|
-
"feature",
|
|
23308
|
-
"capability_tier",
|
|
23309
|
-
"usage_limit",
|
|
23310
|
-
"price_per_unit",
|
|
23311
|
-
"rate_limit",
|
|
23312
|
-
"credits",
|
|
23313
|
-
"seat"
|
|
23314
|
-
]).meta(
|
|
23315
|
-
{
|
|
23316
|
-
id: "EntitlementType",
|
|
23317
|
-
"x-revturbine-schema-persistence": Transient32,
|
|
23318
|
-
"x-revturbine-schema-exposure": External15
|
|
23373
|
+
const findings = [];
|
|
23374
|
+
for (const bucket of publicByTuple.values()) {
|
|
23375
|
+
if (bucket.ids.length < 2) continue;
|
|
23376
|
+
const allIds = [...bucket.ids].sort();
|
|
23377
|
+
const segmentLabel = bucket.segment === "_default" ? "no segment" : `segment ${bucket.segment}`;
|
|
23378
|
+
const parentLabel = parentField === "plan_id" ? "plan" : "add-on";
|
|
23379
|
+
for (const id11 of bucket.ids) {
|
|
23380
|
+
findings.push(
|
|
23381
|
+
finding(
|
|
23382
|
+
"VAL-PLN-06",
|
|
23383
|
+
{
|
|
23384
|
+
object_type: objectType,
|
|
23385
|
+
object_id: id11,
|
|
23386
|
+
field: "visibility",
|
|
23387
|
+
studio: "plans-entitlements"
|
|
23388
|
+
},
|
|
23389
|
+
{
|
|
23390
|
+
message: `Variation '${id11}' is one of ${bucket.ids.length} marked Public for the same ${parentLabel}, billing period '${bucket.period}', and ${segmentLabel} \u2014 only one may be Public.`,
|
|
23391
|
+
detail: `Set all but one of [${allIds.join(", ")}] to Unlisted or Legacy before deploying.`
|
|
23392
|
+
}
|
|
23393
|
+
)
|
|
23394
|
+
);
|
|
23395
|
+
}
|
|
23319
23396
|
}
|
|
23320
|
-
|
|
23321
|
-
|
|
23322
|
-
|
|
23323
|
-
|
|
23324
|
-
|
|
23325
|
-
|
|
23397
|
+
return findings;
|
|
23398
|
+
}
|
|
23399
|
+
function fieldLabel(path3) {
|
|
23400
|
+
if (!path3 || path3.length === 0) return "This value";
|
|
23401
|
+
return String(path3[path3.length - 1]);
|
|
23402
|
+
}
|
|
23403
|
+
function messageForZodIssue(issue) {
|
|
23404
|
+
const field2 = fieldLabel(issue.path);
|
|
23405
|
+
switch (issue.code) {
|
|
23406
|
+
case "invalid_type":
|
|
23407
|
+
return issue.input === void 0 ? `${field2} is required.` : `${field2} must be a ${issue.expected ?? "valid value"}.`;
|
|
23408
|
+
case "invalid_value": {
|
|
23409
|
+
const values = (issue.values ?? []).filter(
|
|
23410
|
+
(v) => ["string", "number", "boolean"].includes(typeof v)
|
|
23411
|
+
);
|
|
23412
|
+
return values.length > 0 ? `${field2} must be one of: ${values.map((v) => `'${String(v)}'`).join(", ")}.` : `${field2} must be one of the allowed values.`;
|
|
23413
|
+
}
|
|
23414
|
+
case "invalid_format":
|
|
23415
|
+
return `${field2} isn't in a valid format.`;
|
|
23416
|
+
case "too_small":
|
|
23417
|
+
return `${field2} is too small.`;
|
|
23418
|
+
case "too_big":
|
|
23419
|
+
return `${field2} is too large.`;
|
|
23420
|
+
case "unrecognized_keys":
|
|
23421
|
+
return `${field2} isn't a recognized setting.`;
|
|
23422
|
+
default:
|
|
23423
|
+
return issue.message ?? `${field2} is invalid.`;
|
|
23326
23424
|
}
|
|
23327
|
-
|
|
23328
|
-
|
|
23329
|
-
|
|
23330
|
-
|
|
23331
|
-
|
|
23332
|
-
|
|
23333
|
-
|
|
23334
|
-
|
|
23335
|
-
|
|
23336
|
-
|
|
23425
|
+
}
|
|
23426
|
+
function targetRefForIssue(issue, basePath) {
|
|
23427
|
+
const path3 = [...basePath, ...issue.path ?? []].map(
|
|
23428
|
+
(seg2) => typeof seg2 === "number" ? seg2 : String(seg2)
|
|
23429
|
+
);
|
|
23430
|
+
return { path: path3 };
|
|
23431
|
+
}
|
|
23432
|
+
function zodErrorToFindings(error2, opts = {}) {
|
|
23433
|
+
const basePath = opts.basePath ?? [];
|
|
23434
|
+
return error2.issues.map((issue) => ({
|
|
23435
|
+
code: issue.code ?? "invalid",
|
|
23436
|
+
severity: "error_draft",
|
|
23437
|
+
targetRef: targetRefForIssue(issue, basePath),
|
|
23438
|
+
message: messageForZodIssue(issue),
|
|
23439
|
+
...opts.specRef ? { specRef: opts.specRef } : {}
|
|
23440
|
+
}));
|
|
23441
|
+
}
|
|
23442
|
+
function spotlights(finding2, focus) {
|
|
23443
|
+
if (!focus) return false;
|
|
23444
|
+
const { object_type, object_id } = finding2.targetRef;
|
|
23445
|
+
if (focus.object_id != null && object_id !== focus.object_id) return false;
|
|
23446
|
+
if (focus.object_type != null && object_type !== focus.object_type) return false;
|
|
23447
|
+
return focus.object_id != null || focus.object_type != null;
|
|
23448
|
+
}
|
|
23449
|
+
function evaluate(graph, opts = {}) {
|
|
23450
|
+
const findings = [];
|
|
23451
|
+
if (opts.structuralErrors) {
|
|
23452
|
+
const errors2 = Array.isArray(opts.structuralErrors) ? opts.structuralErrors : [opts.structuralErrors];
|
|
23453
|
+
for (const error2 of errors2) findings.push(...zodErrorToFindings(error2));
|
|
23337
23454
|
}
|
|
23338
|
-
);
|
|
23339
|
-
|
|
23340
|
-
|
|
23341
|
-
var DescriptionField2 = z310.string().max(500).optional();
|
|
23342
|
-
var MetadataField2 = z310.record(z310.string(), z310.unknown()).default({});
|
|
23343
|
-
var ThresholdPercentField2 = z310.number().int().min(10).max(100).multipleOf(10);
|
|
23344
|
-
var NullableDatetimeField2 = z310.string().datetime().nullable().default(null);
|
|
23345
|
-
var AnchorFields2 = z310.object({
|
|
23346
|
-
environment_id: z310.string().min(1).default("production").meta({ ...Unrestricted39, readOnly: true })
|
|
23347
|
-
}).meta({ id: "null", "x-revturbine-schema-persistence": Transient32, "x-revturbine-schema-exposure": Internal29 });
|
|
23348
|
-
var VersionFields2 = z310.object({
|
|
23349
|
-
// Which playbook version (the review/deploy unit — was `change_set_id`) staged
|
|
23350
|
-
// this ledger row; null once it is the deployed live row.
|
|
23351
|
-
playbook_version_id: z310.string().nullable().default(null).meta(Unrestricted39),
|
|
23352
|
-
is_current: z310.boolean().default(true).meta({ ...Unrestricted39, readOnly: true }),
|
|
23353
|
-
is_deleted: z310.boolean().default(false).meta({ ...Unrestricted39, readOnly: true }),
|
|
23354
|
-
delete_date: z310.string().datetime().nullable().default(null).meta({ ...Unrestricted39, readOnly: true }),
|
|
23355
|
-
// Monotonic version number within a lineage (v1, v2, v3 …); `base_sequence` is
|
|
23356
|
-
// the live sequence this version was forked from (null for the first version),
|
|
23357
|
-
// so a stale draft is detected when live has moved past it.
|
|
23358
|
-
sequence: z310.number().int().min(1).default(1).meta({ ...Unrestricted39, readOnly: true }),
|
|
23359
|
-
base_sequence: z310.number().int().nullable().default(null).meta({ ...Unrestricted39, readOnly: true })
|
|
23360
|
-
}).meta({ id: "null", "x-revturbine-schema-persistence": Transient32, "x-revturbine-schema-exposure": Internal29 });
|
|
23361
|
-
var AnchorBaseSchema2 = IdField2.merge(TimestampFields2).merge(TenantIdField2).merge(AnchorFields2).extend({
|
|
23362
|
-
handle: HandleField2.meta({ ...Unrestricted39, readOnly: true }),
|
|
23363
|
-
active: z310.boolean().default(true).meta({ ...Unrestricted39, readOnly: true })
|
|
23364
|
-
});
|
|
23365
|
-
function makeAnchor2(id11) {
|
|
23366
|
-
return AnchorBaseSchema2.meta({
|
|
23367
|
-
id: id11,
|
|
23368
|
-
"x-revturbine-schema-persistence": Persisted24,
|
|
23369
|
-
"x-revturbine-schema-exposure": Internal29
|
|
23370
|
-
});
|
|
23455
|
+
findings.push(...runSemanticRules(graph, { knownMetricIds: opts.knownMetricIds }));
|
|
23456
|
+
if (!opts.focus) return findings;
|
|
23457
|
+
return findings.map((f) => spotlights(f, opts.focus) ? { ...f, spotlight: true } : f);
|
|
23371
23458
|
}
|
|
23372
|
-
var SeveritySchema22 = z310.enum(["info", "warning", "critical"]).meta({ id: "Severity", "x-revturbine-schema-persistence": Transient32, "x-revturbine-schema-exposure": Internal29 });
|
|
23373
|
-
var CtaActionTypeSchema2 = z310.enum([
|
|
23374
|
-
"open_checkout",
|
|
23375
|
-
"view_plans",
|
|
23376
|
-
"book_demo",
|
|
23377
|
-
"contact_sales",
|
|
23378
|
-
"complete_onboarding",
|
|
23379
|
-
"invite_teammate",
|
|
23380
|
-
"refer_friend",
|
|
23381
|
-
"verify_work_email",
|
|
23382
|
-
"update_payment_method",
|
|
23383
|
-
"enable_auto_renewal",
|
|
23384
|
-
"manage_subscription",
|
|
23385
|
-
"switch_billing_period",
|
|
23386
|
-
"extend_trial",
|
|
23387
|
-
"open_rt_placement",
|
|
23388
|
-
"dismiss",
|
|
23389
|
-
"snooze",
|
|
23390
|
-
"custom"
|
|
23391
|
-
]).meta({ id: "CtaActionType", "x-revturbine-schema-persistence": Transient32, "x-revturbine-schema-exposure": External15 });
|
|
23392
|
-
var ObjectiveField2 = HandleField2.optional();
|
|
23393
23459
|
var IdentityKind2 = {
|
|
23394
23460
|
/** Author-given, human-meaningful handle (plans, entitlements, segments, …). */
|
|
23395
23461
|
Named: "named",
|
|
@@ -25970,7 +26036,7 @@ function repairDeprecatedFields(config, schema = PlaybookObjectSchema2) {
|
|
|
25970
26036
|
}
|
|
25971
26037
|
|
|
25972
26038
|
// src/schema/version.ts
|
|
25973
|
-
var SCHEMA_VERSION = "0.1.
|
|
26039
|
+
var SCHEMA_VERSION = "0.1.524";
|
|
25974
26040
|
|
|
25975
26041
|
// src/lib/credentials.ts
|
|
25976
26042
|
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.21.
|
|
3
|
+
"version": "0.21.2",
|
|
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": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"verify": "npm run typecheck && npm run lint && npm run check:schema && npm run test"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@revturbine/sdk": ">=0.
|
|
33
|
+
"@revturbine/sdk": ">=0.12.5 <1",
|
|
34
34
|
"commander": "^15.0.0",
|
|
35
35
|
"semver": "^7.8.5",
|
|
36
36
|
"zod": "4.4.3"
|