@aglyn/aglyn 1.0.0-beta.270 → 1.0.0-beta.272
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/package.json +11 -11
- package/src/lib/app-utils/account-preferences.d.ts +50 -0
- package/src/lib/app-utils/account-preferences.js +96 -0
- package/src/lib/app-utils/account-preferences.js.map +1 -1
- package/src/lib/app-utils/activity-labels.js +2 -0
- package/src/lib/app-utils/activity-labels.js.map +1 -1
- package/src/lib/app-utils/analytics-events.d.ts +16 -2
- package/src/lib/app-utils/analytics-events.js +2 -0
- package/src/lib/app-utils/analytics-events.js.map +1 -1
- package/src/lib/app-utils/append-only-history.d.ts +94 -0
- package/src/lib/app-utils/append-only-history.js +73 -0
- package/src/lib/app-utils/append-only-history.js.map +1 -0
- package/src/lib/app-utils/bundle-intent.d.ts +186 -0
- package/src/lib/app-utils/bundle-intent.js +386 -0
- package/src/lib/app-utils/bundle-intent.js.map +1 -0
- package/src/lib/app-utils/client-build.d.ts +207 -0
- package/src/lib/app-utils/client-build.js +237 -0
- package/src/lib/app-utils/client-build.js.map +1 -0
- package/src/lib/app-utils/console-routes.d.ts +4 -0
- package/src/lib/app-utils/console-routes.js +2 -0
- package/src/lib/app-utils/console-routes.js.map +1 -1
- package/src/lib/app-utils/docs-help-sections.generated.js +13 -6
- package/src/lib/app-utils/docs-help-sections.generated.js.map +1 -1
- package/src/lib/app-utils/docs-help.generated.d.ts +11 -5
- package/src/lib/app-utils/docs-help.generated.js +31 -2
- package/src/lib/app-utils/docs-help.generated.js.map +1 -1
- package/src/lib/app-utils/docs-index.generated.js +105 -35
- package/src/lib/app-utils/docs-index.generated.js.map +1 -1
- package/src/lib/app-utils/margin-utilization.js +6 -4
- package/src/lib/app-utils/margin-utilization.js.map +1 -1
- package/src/lib/app-utils/media-filter.d.ts +26 -0
- package/src/lib/app-utils/media-filter.js +32 -0
- package/src/lib/app-utils/media-filter.js.map +1 -1
- package/src/lib/app-utils/onboarding-deep-link.d.ts +36 -2
- package/src/lib/app-utils/onboarding-deep-link.js +48 -5
- package/src/lib/app-utils/onboarding-deep-link.js.map +1 -1
- package/src/lib/app-utils/operator-alerts.js +21 -0
- package/src/lib/app-utils/operator-alerts.js.map +1 -1
- package/src/lib/app-utils/owner-approval-record.d.ts +102 -0
- package/src/lib/app-utils/owner-approval-record.js +148 -0
- package/src/lib/app-utils/owner-approval-record.js.map +1 -0
- package/src/lib/app-utils/plan-card-meters.d.ts +96 -0
- package/src/lib/app-utils/plan-card-meters.js +197 -0
- package/src/lib/app-utils/plan-card-meters.js.map +1 -0
- package/src/lib/app-utils/plan-entitlements.d.ts +183 -67
- package/src/lib/app-utils/plan-entitlements.js +213 -58
- package/src/lib/app-utils/plan-entitlements.js.map +1 -1
- package/src/lib/app-utils/release-flags.d.ts +1 -1
- package/src/lib/app-utils/release-flags.js +22 -0
- package/src/lib/app-utils/release-flags.js.map +1 -1
- package/src/lib/app-utils/server.d.ts +4 -0
- package/src/lib/app-utils/server.js +7 -0
- package/src/lib/app-utils/server.js.map +1 -1
- package/src/lib/app-utils/site-care-project.d.ts +227 -0
- package/src/lib/app-utils/site-care-project.js +423 -0
- package/src/lib/app-utils/site-care-project.js.map +1 -0
- package/src/lib/app-utils/site-care.d.ts +291 -0
- package/src/lib/app-utils/site-care.js +310 -0
- package/src/lib/app-utils/site-care.js.map +1 -0
- package/src/lib/app-utils/upgrade-proposal.d.ts +29 -4
- package/src/lib/app-utils/upgrade-proposal.js +60 -9
- package/src/lib/app-utils/upgrade-proposal.js.map +1 -1
- package/src/lib/foundation/definitions/org-billing.types.d.ts +40 -10
- package/src/lib/foundation/definitions/org-billing.types.js.map +1 -1
- package/src/lib/foundation/definitions/organization.types.d.ts +3 -1
- package/src/lib/foundation/definitions/organization.types.js.map +1 -1
- package/src/lib/foundation/definitions/platform.types.d.ts +20 -0
- package/src/lib/foundation/definitions/platform.types.js.map +1 -1
- package/src/lib/foundation/index.d.ts +1 -1
- package/src/lib/foundation/index.js.map +1 -1
- package/src/lib/plugin-manager/feature-plugins.d.ts +48 -0
- package/src/lib/plugin-manager/feature-plugins.js.map +1 -1
- package/src/lib/plugin-manager/first-party-plugins.generated.js +16 -0
- package/src/lib/plugin-manager/first-party-plugins.generated.js.map +1 -1
- package/src/lib/plugin-manager/plugin-ai-capabilities.d.ts +19 -0
- package/src/lib/plugin-manager/plugin-ai-capabilities.js.map +1 -1
- package/src/lib/plugin-manager/plugin-domain-search.d.ts +81 -0
- package/src/lib/plugin-manager/plugin-domain-search.js +63 -0
- package/src/lib/plugin-manager/plugin-domain-search.js.map +1 -0
- package/src/lib/plugin-manager/plugin-entitlements.d.ts +23 -5
- package/src/lib/plugin-manager/plugin-entitlements.js +10 -0
- package/src/lib/plugin-manager/plugin-entitlements.js.map +1 -1
- package/src/lib/plugin-manager/plugin-media-ingest.d.ts +18 -1
- package/src/lib/plugin-manager/plugin-media-ingest.js.map +1 -1
- package/src/lib/plugin-manager/plugin-site-resources.d.ts +74 -0
- package/src/lib/plugin-manager/plugin-site-resources.js +135 -0
- package/src/lib/plugin-manager/plugin-site-resources.js.map +1 -0
- package/src/lib/plugin-manager/purchase-gate-preclearance.d.ts +61 -0
- package/src/lib/plugin-manager/purchase-gate-preclearance.js +102 -0
- package/src/lib/plugin-manager/purchase-gate-preclearance.js.map +1 -0
|
@@ -362,7 +362,10 @@ export const PLAN_ENTITLEMENTS = {
|
|
|
362
362
|
removeBranding: true,
|
|
363
363
|
scheduledPublishing: false,
|
|
364
364
|
aiAssist: true,
|
|
365
|
-
|
|
365
|
+
// One pool (AGL-3965): the plan's included credits pay for generation
|
|
366
|
+
// as well as assist on every paid plan, and an Aglyn AI tier adds
|
|
367
|
+
// credits on top rather than opening this door.
|
|
368
|
+
aiGenerative: true,
|
|
366
369
|
workflows: true,
|
|
367
370
|
dataStore: true,
|
|
368
371
|
videoMedia: false,
|
|
@@ -481,7 +484,7 @@ export const PLAN_ENTITLEMENTS = {
|
|
|
481
484
|
removeBranding: true,
|
|
482
485
|
scheduledPublishing: false,
|
|
483
486
|
aiAssist: true,
|
|
484
|
-
aiGenerative:
|
|
487
|
+
aiGenerative: true,
|
|
485
488
|
workflows: true,
|
|
486
489
|
dataStore: true,
|
|
487
490
|
videoMedia: true,
|
|
@@ -552,7 +555,7 @@ export const PLAN_ENTITLEMENTS = {
|
|
|
552
555
|
removeBranding: true,
|
|
553
556
|
scheduledPublishing: true,
|
|
554
557
|
aiAssist: true,
|
|
555
|
-
aiGenerative:
|
|
558
|
+
aiGenerative: true,
|
|
556
559
|
workflows: true,
|
|
557
560
|
dataStore: true,
|
|
558
561
|
videoMedia: true,
|
|
@@ -626,7 +629,7 @@ export const PLAN_ENTITLEMENTS = {
|
|
|
626
629
|
removeBranding: true,
|
|
627
630
|
scheduledPublishing: true,
|
|
628
631
|
aiAssist: true,
|
|
629
|
-
aiGenerative:
|
|
632
|
+
aiGenerative: true,
|
|
630
633
|
workflows: true,
|
|
631
634
|
dataStore: true,
|
|
632
635
|
videoMedia: true,
|
|
@@ -697,7 +700,7 @@ export const PLAN_ENTITLEMENTS = {
|
|
|
697
700
|
removeBranding: true,
|
|
698
701
|
scheduledPublishing: true,
|
|
699
702
|
aiAssist: true,
|
|
700
|
-
aiGenerative:
|
|
703
|
+
aiGenerative: true,
|
|
701
704
|
workflows: true,
|
|
702
705
|
dataStore: true,
|
|
703
706
|
videoMedia: true,
|
|
@@ -772,7 +775,7 @@ export const PLAN_ENTITLEMENTS = {
|
|
|
772
775
|
removeBranding: true,
|
|
773
776
|
scheduledPublishing: true,
|
|
774
777
|
aiAssist: true,
|
|
775
|
-
aiGenerative:
|
|
778
|
+
aiGenerative: true,
|
|
776
779
|
workflows: true,
|
|
777
780
|
dataStore: true,
|
|
778
781
|
videoMedia: true,
|
|
@@ -1016,52 +1019,149 @@ fillPluginPlanEntitlements(PLAN_ENTITLEMENTS);
|
|
|
1016
1019
|
* deal) — `planSellsSiteCare` is that rule. `resolveOrgEntitlements` flips
|
|
1017
1020
|
* the org-wide `features.siteCare` from any purchased quantity >= 1.
|
|
1018
1021
|
*/ export const SITE_CARE_ADDON_MONTHLY_USD = 49;
|
|
1022
|
+
/**
|
|
1023
|
+
* Site Care's included time (AGL-3959): about an hour of staff work a month,
|
|
1024
|
+
* no rollover. `SITE_CARE_INCLUDED_BLOCK_MINUTES` is the step each request is
|
|
1025
|
+
* counted against it in, always rounded up — a 10-minute change uses one
|
|
1026
|
+
* 15-minute block. The timer's actual minutes are still logged beside it.
|
|
1027
|
+
*/ export const SITE_CARE_INCLUDED_MINUTES = 60;
|
|
1028
|
+
/** The block a request counts against the included hour in (AGL-3959). */ export const SITE_CARE_INCLUDED_BLOCK_MINUTES = 15;
|
|
1029
|
+
/**
|
|
1030
|
+
* Site Care extra time (AGL-3959): $79 per STARTED hour past the included
|
|
1031
|
+
* hour in a month. Billed in whole hours, rounded up — any part of an hour is
|
|
1032
|
+
* the full rate — and never less than the hours the owner approved. Only with
|
|
1033
|
+
* the owner's recorded yes, as an invoice item on the next subscription
|
|
1034
|
+
* invoice; never recurring. `site-care.ts` holds the arithmetic.
|
|
1035
|
+
*/ export const SITE_CARE_EXTRA_HOUR_USD = 79;
|
|
1036
|
+
/**
|
|
1037
|
+
* Site Care projects (AGL-3970): work that adds a page, a form, a design or
|
|
1038
|
+
* a campaign is a flat quote, never hourly. The quote is the estimated hours
|
|
1039
|
+
* × `SITE_CARE_EXTRA_HOUR_USD`, rounded up to the whole hour, and never below
|
|
1040
|
+
* the published starting price of the kind of project it is. These three are
|
|
1041
|
+
* those starting prices, as `/pricing` publishes them.
|
|
1042
|
+
*/ export const SITE_CARE_PROJECT_LANDING_PAGE_FROM_USD = 249;
|
|
1043
|
+
/** A redesign's published starting price (AGL-3970). */ export const SITE_CARE_PROJECT_REDESIGN_FROM_USD = 749;
|
|
1044
|
+
/** A logo or brand kit's published starting price (AGL-3970). */ export const SITE_CARE_PROJECT_BRAND_KIT_FROM_USD = 349;
|
|
1045
|
+
/**
|
|
1046
|
+
* A project priced ABOVE this is billed half up front and half at launch, on
|
|
1047
|
+
* two invoices from the same record; at or below it, in full up front
|
|
1048
|
+
* (AGL-3970). `site-care-project.ts` holds the arithmetic.
|
|
1049
|
+
*/ export const SITE_CARE_PROJECT_SPLIT_ABOVE_USD = 500;
|
|
1019
1050
|
/**
|
|
1020
1051
|
* POS Pro register add-on (AGL-329): $89/mo per extra register/location
|
|
1021
1052
|
* (Shopify POS Pro parity). Purchased add-ons land as a per-org
|
|
1022
1053
|
* `posRegisters` entitlement override, which
|
|
1023
1054
|
* `resolveOrgEntitlements` already applies over the plan default.
|
|
1024
1055
|
*/ export const POS_REGISTER_ADDON_MONTHLY_USD = 89;
|
|
1056
|
+
/** The tiers, smallest first — the order every picker lists them in. */ export const AI_TIER_IDS = [
|
|
1057
|
+
'spark',
|
|
1058
|
+
'boost',
|
|
1059
|
+
'plus',
|
|
1060
|
+
'max',
|
|
1061
|
+
'ultra',
|
|
1062
|
+
'studio'
|
|
1063
|
+
];
|
|
1064
|
+
export const AI_TIERS = {
|
|
1065
|
+
spark: {
|
|
1066
|
+
label: 'Spark',
|
|
1067
|
+
monthlyUsd: 9,
|
|
1068
|
+
yearlyUsd: 108,
|
|
1069
|
+
credits: 4000
|
|
1070
|
+
},
|
|
1071
|
+
boost: {
|
|
1072
|
+
label: 'Boost',
|
|
1073
|
+
monthlyUsd: 19,
|
|
1074
|
+
yearlyUsd: 228,
|
|
1075
|
+
credits: 9000
|
|
1076
|
+
},
|
|
1077
|
+
plus: {
|
|
1078
|
+
label: 'Plus',
|
|
1079
|
+
monthlyUsd: 39,
|
|
1080
|
+
yearlyUsd: 468,
|
|
1081
|
+
credits: 19000
|
|
1082
|
+
},
|
|
1083
|
+
max: {
|
|
1084
|
+
label: 'Max',
|
|
1085
|
+
monthlyUsd: 69,
|
|
1086
|
+
yearlyUsd: 828,
|
|
1087
|
+
credits: 34000
|
|
1088
|
+
},
|
|
1089
|
+
ultra: {
|
|
1090
|
+
label: 'Ultra',
|
|
1091
|
+
monthlyUsd: 99,
|
|
1092
|
+
yearlyUsd: 1188,
|
|
1093
|
+
credits: 49000
|
|
1094
|
+
},
|
|
1095
|
+
studio: {
|
|
1096
|
+
label: 'Studio',
|
|
1097
|
+
monthlyUsd: 299,
|
|
1098
|
+
yearlyUsd: 3588,
|
|
1099
|
+
credits: 149000
|
|
1100
|
+
}
|
|
1101
|
+
};
|
|
1025
1102
|
/**
|
|
1026
|
-
* The
|
|
1027
|
-
*
|
|
1028
|
-
*
|
|
1029
|
-
*
|
|
1030
|
-
*
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
* Pro $9 of $19, Business $19 of $39, Scale $34 of $69, Advanced $49 of
|
|
1039
|
-
* $99, Agency $149 of $299 — which is the same line-margin floor
|
|
1040
|
-
* (`ASSIST_CREDIT_MIN_MARGIN_PCT`) every retail assist rate clears.
|
|
1041
|
-
* `tier-margin-floor.spec.ts` holds the whole tier non-negative with the
|
|
1042
|
-
* add-on band at 100% and the add-on's revenue counted, and pins each band's
|
|
1043
|
-
* share of its price.
|
|
1044
|
-
*
|
|
1045
|
-
* ## Free and Enterprise
|
|
1046
|
-
*
|
|
1047
|
-
* Free is 0: the plan sells no add-on (`aiAddonMonthlyUsd` is null), so a
|
|
1048
|
-
* quantity written onto a Free org adds nothing. Enterprise is finite at
|
|
1049
|
-
* twice Agency's, the rule every Enterprise fallback follows since the
|
|
1050
|
-
* 2026-09-07 decision (AGL-2654) — never `UNLIMITED`, for the reason
|
|
1051
|
-
* `ENTERPRISE_ASSIST_CREDITS_PER_MONTH` gives: an unbounded band reads back
|
|
1052
|
-
* as zero off the wire. Enterprise carries `aiGenerative` in the agreement
|
|
1053
|
-
* and its price is null too, so this figure is what a contract that names
|
|
1054
|
-
* the add-on starts from before its own number is written.
|
|
1055
|
-
*/ export const AI_ADDON_CREDITS_PER_MONTH = {
|
|
1056
|
-
free: 0,
|
|
1057
|
-
starter: 4000,
|
|
1058
|
-
pro: 9000,
|
|
1059
|
-
business: 19000,
|
|
1060
|
-
scale: 34000,
|
|
1061
|
-
advanced: 49000,
|
|
1062
|
-
agency: 149000,
|
|
1063
|
-
enterprise: 298000
|
|
1103
|
+
* The tier an add-on bought before AGL-3965 is (AGL-3965): the one with the
|
|
1104
|
+
* same price and the same band the plan sold it at, so a workspace that
|
|
1105
|
+
* held "the Pro add-on" holds Boost — $19, 9,000 credits — and neither its
|
|
1106
|
+
* bill nor its credits move. Read when `aiTier` is absent and to classify a
|
|
1107
|
+
* per-plan `STRIPE_PRICE_{PLAN}_AI_ADDON` item still on a subscription.
|
|
1108
|
+
*/ export const LEGACY_AI_ADDON_TIER_BY_PLAN = {
|
|
1109
|
+
starter: 'spark',
|
|
1110
|
+
pro: 'boost',
|
|
1111
|
+
business: 'plus',
|
|
1112
|
+
scale: 'max',
|
|
1113
|
+
advanced: 'ultra',
|
|
1114
|
+
agency: 'studio'
|
|
1064
1115
|
};
|
|
1116
|
+
/**
|
|
1117
|
+
* The tier a purchase that names a plan and no tier means (AGL-3965): a
|
|
1118
|
+
* `?plan=pro&ai=1` deep link, a checkout posting `aiAddon: true` alone. The
|
|
1119
|
+
* tier with that plan's old price and band, so a link published before tiers
|
|
1120
|
+
* existed still sells what it quoted. Null where the plan sells no tier.
|
|
1121
|
+
*/ export function defaultAiTierForPlan(plan) {
|
|
1122
|
+
var _LEGACY_AI_ADDON_TIER_BY_PLAN_plan;
|
|
1123
|
+
if (!planSellsAiTiers(plan)) return null;
|
|
1124
|
+
return (_LEGACY_AI_ADDON_TIER_BY_PLAN_plan = LEGACY_AI_ADDON_TIER_BY_PLAN[plan]) != null ? _LEGACY_AI_ADDON_TIER_BY_PLAN_plan : null;
|
|
1125
|
+
}
|
|
1126
|
+
/** Whether a value is one of the tier ids. */ export function isAiTierId(value) {
|
|
1127
|
+
return typeof value === 'string' && AI_TIER_IDS.includes(value);
|
|
1128
|
+
}
|
|
1129
|
+
/** `ai:<tier>` for a tier. */ export function aiTierAddonKey(tier) {
|
|
1130
|
+
return `ai:${tier}`;
|
|
1131
|
+
}
|
|
1132
|
+
/**
|
|
1133
|
+
* The tier an `ai:<tier>` key names, or null for anything else — another
|
|
1134
|
+
* add-on's key, a bare `ai`, an unknown tier, a non-string. Exact and
|
|
1135
|
+
* case-sensitive: a key is read off a link, and guessing is the expensive
|
|
1136
|
+
* direction to be wrong in (`parseOnboardingPlanIntent` reads `?ai=` the
|
|
1137
|
+
* same way).
|
|
1138
|
+
*/ export function parseAiTierAddonKey(key) {
|
|
1139
|
+
if (typeof key !== 'string' || !key.startsWith('ai:')) return null;
|
|
1140
|
+
const tier = key.slice(3);
|
|
1141
|
+
return isAiTierId(tier) ? tier : null;
|
|
1142
|
+
}
|
|
1143
|
+
/**
|
|
1144
|
+
* Every tier as an `ai:<tier>` add-on, smallest first — what a picker that
|
|
1145
|
+
* offers "Aglyn AI" beside the other add-ons lists. Empty for a plan that
|
|
1146
|
+
* sells no tier (Free, Enterprise) when a plan is given.
|
|
1147
|
+
*/ export function listAiTierAddons(plan) {
|
|
1148
|
+
if (plan !== undefined && !planSellsAiTiers(plan)) return [];
|
|
1149
|
+
return AI_TIER_IDS.map((tier)=>({
|
|
1150
|
+
key: aiTierAddonKey(tier),
|
|
1151
|
+
tier,
|
|
1152
|
+
label: AI_TIERS[tier].label,
|
|
1153
|
+
monthlyUsd: AI_TIERS[tier].monthlyUsd,
|
|
1154
|
+
yearlyUsd: AI_TIERS[tier].yearlyUsd,
|
|
1155
|
+
credits: AI_TIERS[tier].credits
|
|
1156
|
+
}));
|
|
1157
|
+
}
|
|
1158
|
+
/**
|
|
1159
|
+
* Whether a plan may buy an Aglyn AI tier (AGL-3965): every paid self-serve
|
|
1160
|
+
* plan. Not Free, which has no subscription to carry it, and not Enterprise,
|
|
1161
|
+
* whose AI is in the agreement.
|
|
1162
|
+
*/ export function planSellsAiTiers(plan) {
|
|
1163
|
+
return planSellsSiteCare(plan);
|
|
1164
|
+
}
|
|
1065
1165
|
/**
|
|
1066
1166
|
* The generative add-on's name as a person sees it (AGL-2896): the brand,
|
|
1067
1167
|
* then "AI". Read from the platform brand by default and from the org's
|
|
@@ -1108,7 +1208,6 @@ fillPluginPlanEntitlements(PLAN_ENTITLEMENTS);
|
|
|
1108
1208
|
extraDataGbMonthlyUsd: null,
|
|
1109
1209
|
extraApiRequestsUsdPer1k: null,
|
|
1110
1210
|
extraAssistCreditsUsdPer1k: null,
|
|
1111
|
-
aiAddonMonthlyUsd: null,
|
|
1112
1211
|
extraContactsUsdPer1k: null,
|
|
1113
1212
|
extraEmailSendsUsdPer1k: null,
|
|
1114
1213
|
meteredInfraPassThrough: false
|
|
@@ -1129,7 +1228,6 @@ fillPluginPlanEntitlements(PLAN_ENTITLEMENTS);
|
|
|
1129
1228
|
// the silent free overage, and this rate without the band is a fee
|
|
1130
1229
|
// advertised on a quantity the plan never sold.
|
|
1131
1230
|
extraAssistCreditsUsdPer1k: 3,
|
|
1132
|
-
aiAddonMonthlyUsd: 9,
|
|
1133
1231
|
extraContactsUsdPer1k: 1,
|
|
1134
1232
|
// No email band to be "over" — see `emailSendsPerMonth` on the Starter
|
|
1135
1233
|
// entitlements. `emailSendsOverage` returns 0 for any non-positive band,
|
|
@@ -1148,7 +1246,6 @@ fillPluginPlanEntitlements(PLAN_ENTITLEMENTS);
|
|
|
1148
1246
|
extraDataGbMonthlyUsd: 0.36,
|
|
1149
1247
|
extraApiRequestsUsdPer1k: null,
|
|
1150
1248
|
extraAssistCreditsUsdPer1k: 3,
|
|
1151
|
-
aiAddonMonthlyUsd: 19,
|
|
1152
1249
|
extraContactsUsdPer1k: 0.75,
|
|
1153
1250
|
extraEmailSendsUsdPer1k: 2.25,
|
|
1154
1251
|
meteredInfraPassThrough: true
|
|
@@ -1163,7 +1260,6 @@ fillPluginPlanEntitlements(PLAN_ENTITLEMENTS);
|
|
|
1163
1260
|
extraDataGbMonthlyUsd: 0.36,
|
|
1164
1261
|
extraApiRequestsUsdPer1k: 0.5,
|
|
1165
1262
|
extraAssistCreditsUsdPer1k: 2.75,
|
|
1166
|
-
aiAddonMonthlyUsd: 39,
|
|
1167
1263
|
extraContactsUsdPer1k: 0.5,
|
|
1168
1264
|
extraEmailSendsUsdPer1k: 2,
|
|
1169
1265
|
meteredInfraPassThrough: true
|
|
@@ -1178,7 +1274,6 @@ fillPluginPlanEntitlements(PLAN_ENTITLEMENTS);
|
|
|
1178
1274
|
extraDataGbMonthlyUsd: 0.36,
|
|
1179
1275
|
extraApiRequestsUsdPer1k: 0.35,
|
|
1180
1276
|
extraAssistCreditsUsdPer1k: 2.5,
|
|
1181
|
-
aiAddonMonthlyUsd: 69,
|
|
1182
1277
|
extraContactsUsdPer1k: 0.4,
|
|
1183
1278
|
extraEmailSendsUsdPer1k: 1.9,
|
|
1184
1279
|
meteredInfraPassThrough: true
|
|
@@ -1196,7 +1291,6 @@ fillPluginPlanEntitlements(PLAN_ENTITLEMENTS);
|
|
|
1196
1291
|
// or above $0.234 (AGL-3444).
|
|
1197
1292
|
extraApiRequestsUsdPer1k: 0.25,
|
|
1198
1293
|
extraAssistCreditsUsdPer1k: 2.25,
|
|
1199
|
-
aiAddonMonthlyUsd: 99,
|
|
1200
1294
|
// FLOORED at the 50% retail margin, not stepped down again. The ladder
|
|
1201
1295
|
// above it descends $1.00 → $0.75 → $0.50 → $0.40, and one more step
|
|
1202
1296
|
// would have reached $0.25 against a `perContactMonth` cost of $0.20 per
|
|
@@ -1230,7 +1324,6 @@ fillPluginPlanEntitlements(PLAN_ENTITLEMENTS);
|
|
|
1230
1324
|
// FLOORED at the 50% retail margin — see Advanced's.
|
|
1231
1325
|
extraApiRequestsUsdPer1k: 0.25,
|
|
1232
1326
|
extraAssistCreditsUsdPer1k: 2,
|
|
1233
|
-
aiAddonMonthlyUsd: 299,
|
|
1234
1327
|
// $0.40, because the band it meters is now FINITE.
|
|
1235
1328
|
//
|
|
1236
1329
|
// This row has been wrong in both directions. It shipped $0.20 against an
|
|
@@ -1273,7 +1366,6 @@ fillPluginPlanEntitlements(PLAN_ENTITLEMENTS);
|
|
|
1273
1366
|
extraDataGbMonthlyUsd: null,
|
|
1274
1367
|
extraApiRequestsUsdPer1k: null,
|
|
1275
1368
|
extraAssistCreditsUsdPer1k: null,
|
|
1276
|
-
aiAddonMonthlyUsd: null,
|
|
1277
1369
|
extraContactsUsdPer1k: null,
|
|
1278
1370
|
extraEmailSendsUsdPer1k: null,
|
|
1279
1371
|
meteredInfraPassThrough: false
|
|
@@ -1622,8 +1714,11 @@ function trimmedOrNull(value) {
|
|
|
1622
1714
|
const addons = (_ref = org == null ? void 0 : org.seatAddons) != null ? _ref : {};
|
|
1623
1715
|
const seats = (quantity, price)=>Math.max(0, quantity != null ? quantity : 0) * (price != null ? price : 0);
|
|
1624
1716
|
return (annual ? pricing.basePriceAnnualMonthlyUsd : pricing.basePriceMonthlyUsd) + seats(addons.managers, pricing.extraSeatMonthlyUsd) + seats(addons.members, pricing.extraCollaboratorMonthlyUsd) + seats(addons.datasets, pricing.extraDatasetMonthlyUsd) + seats(addons.hosts, pricing.extraHostMonthlyUsd) + seats(addons.posRegisters, POS_REGISTER_ADDON_MONTHLY_USD) + seats(addons.eventCalendar, EVENT_CALENDAR_ADDON_MONTHLY_USD) + seats(siteCareUnits(addons), SITE_CARE_ADDON_MONTHLY_USD) + // A toggle, not a quantity: one purchase covers the org, so a stored
|
|
1625
|
-
// quantity above one bills once.
|
|
1626
|
-
|
|
1717
|
+
// quantity above one bills once, at its tier's price (AGL-3965).
|
|
1718
|
+
aiTierMonthlyUsd(aiTierOfPurchase(org));
|
|
1719
|
+
}
|
|
1720
|
+
/** A tier's monthly price, or 0 for no tier. */ function aiTierMonthlyUsd(tier) {
|
|
1721
|
+
return tier ? AI_TIERS[tier].monthlyUsd : 0;
|
|
1627
1722
|
}
|
|
1628
1723
|
/**
|
|
1629
1724
|
* How many Aglyn AI add-ons a purchase map counts as: 0 or 1 (AGL-2896).
|
|
@@ -2449,6 +2544,65 @@ function resolvePlan(org) {
|
|
|
2449
2544
|
*/ export function hasAiAddon(org) {
|
|
2450
2545
|
return aiAddonUnits(resolvePurchasedAddons(org)) === 1;
|
|
2451
2546
|
}
|
|
2547
|
+
/**
|
|
2548
|
+
* Which Aglyn AI tier the org's purchase map holds (AGL-3965), whether or
|
|
2549
|
+
* not the subscription is still paying for it — `resolveAiTier` is the
|
|
2550
|
+
* reading that drops a dead one. `org.aiTier` when it names a tier;
|
|
2551
|
+
* otherwise, for an add-on bought before tiers existed, the tier with that
|
|
2552
|
+
* plan's old price and band (`LEGACY_AI_ADDON_TIER_BY_PLAN`). Null when no
|
|
2553
|
+
* add-on is held or the plan sells no tier (Free, Enterprise).
|
|
2554
|
+
*/ export function aiTierOfPurchase(org) {
|
|
2555
|
+
var _LEGACY_AI_ADDON_TIER_BY_PLAN_;
|
|
2556
|
+
if (aiAddonUnits(org == null ? void 0 : org.seatAddons) !== 1) return null;
|
|
2557
|
+
if (!planSellsAiTiers(org == null ? void 0 : org.plan)) return null;
|
|
2558
|
+
if (isAiTierId(org == null ? void 0 : org.aiTier)) return org.aiTier;
|
|
2559
|
+
return (_LEGACY_AI_ADDON_TIER_BY_PLAN_ = LEGACY_AI_ADDON_TIER_BY_PLAN[org == null ? void 0 : org.plan]) != null ? _LEGACY_AI_ADDON_TIER_BY_PLAN_ : null;
|
|
2560
|
+
}
|
|
2561
|
+
/**
|
|
2562
|
+
* The Aglyn AI tier that currently applies (AGL-3965): bought, on a
|
|
2563
|
+
* subscription still paying for it, on a plan that sells tiers. The ONE
|
|
2564
|
+
* reading every surface that shows or counts a tier goes through.
|
|
2565
|
+
*/ export function resolveAiTier(org) {
|
|
2566
|
+
return hasAiAddon(org) ? aiTierOfPurchase(org) : null;
|
|
2567
|
+
}
|
|
2568
|
+
/**
|
|
2569
|
+
* What `seatAddons.aiAddon` adds on an Enterprise org (AGL-2896, kept by
|
|
2570
|
+
* AGL-3965): twice Studio's band, the figure the per-plan table carried as
|
|
2571
|
+
* twice Agency's (the rule every Enterprise fallback follows since AGL-2654),
|
|
2572
|
+
* and still what a contract that names the add-on starts from before its own
|
|
2573
|
+
* number is written. Enterprise buys no tier — its AI is in the agreement —
|
|
2574
|
+
* so this is the contract figure kept, not a price; finite, never
|
|
2575
|
+
* `UNLIMITED`, for the reason `ENTERPRISE_ASSIST_CREDITS_PER_MONTH` gives.
|
|
2576
|
+
*/ export const ENTERPRISE_AI_ADDON_CREDITS_PER_MONTH = AI_TIERS.studio.credits * 2;
|
|
2577
|
+
/**
|
|
2578
|
+
* The Aglyn AI add-on's per-unit quota as `resolveOrgEntitlements` folds it
|
|
2579
|
+
* (AGL-3965): the purchased tier's credits, on a plan that sells tiers;
|
|
2580
|
+
* Enterprise's contract figure (`ENTERPRISE_AI_ADDON_CREDITS_PER_MONTH`);
|
|
2581
|
+
* else 0 (Free). The AI plugin declares its seat add-on with this as
|
|
2582
|
+
* `quota.perUnit`.
|
|
2583
|
+
*/ export function aiTierQuotaPerUnit(org, plan) {
|
|
2584
|
+
if (plan === 'enterprise') return ENTERPRISE_AI_ADDON_CREDITS_PER_MONTH;
|
|
2585
|
+
if (!planSellsAiTiers(plan)) return 0;
|
|
2586
|
+
const tier = aiTierOfPurchase(org);
|
|
2587
|
+
return tier ? AI_TIERS[tier].credits : 0;
|
|
2588
|
+
}
|
|
2589
|
+
/**
|
|
2590
|
+
* The credits a month the org's Aglyn AI add-on adds to its plan's included
|
|
2591
|
+
* band (AGL-3965) — 0 with none held. The SAME figure `resolveOrgEntitlements`
|
|
2592
|
+
* folds into `assistCreditsPerMonth` (`aiTierQuotaPerUnit`), so a surface
|
|
2593
|
+
* quoting "your tier adds" and the meter agree.
|
|
2594
|
+
*/ export function aiTierCreditsPerMonth(org) {
|
|
2595
|
+
if (!hasAiAddon(org)) return 0;
|
|
2596
|
+
return aiTierQuotaPerUnit(org, resolveEffectivePlan(org));
|
|
2597
|
+
}
|
|
2598
|
+
/**
|
|
2599
|
+
* Whether this org can buy or change an Aglyn AI tier itself (AGL-3965): a
|
|
2600
|
+
* plan that sells tiers, and not one a staff comp grants — a comp has no
|
|
2601
|
+
* subscription to put the tier on (`compPricing`).
|
|
2602
|
+
*/ export function orgCanBuyAiTier(org) {
|
|
2603
|
+
return !resolvePlanComp(org) && planSellsAiTiers(resolveEffectivePlan(org));
|
|
2604
|
+
}
|
|
2605
|
+
/** "Aglyn AI Boost": the product name, then the tier's. */ export const aiTierName = (tier, brand = PLATFORM_BRAND_NAME)=>`${aiAddonName(brand)} ${AI_TIERS[tier].label}`;
|
|
2452
2606
|
/**
|
|
2453
2607
|
* Whether the org's Site Care add-on currently applies (AGL-3954): bought,
|
|
2454
2608
|
* and on a subscription that is still paying for it, so a dead subscription
|
|
@@ -2652,7 +2806,7 @@ function resolvePlan(org) {
|
|
|
2652
2806
|
// `hostLimit` and purchased sites do. The per-unit figure is the PLAN's,
|
|
2653
2807
|
// read off the effective plan rather than the stored one, so a dead
|
|
2654
2808
|
// subscription that resolved to free adds free's figure.
|
|
2655
|
-
const folded = foldPluginSeatAddons(resolved, purchased, resolvePlan(org));
|
|
2809
|
+
const folded = foldPluginSeatAddons(resolved, purchased, resolvePlan(org), org != null ? org : {});
|
|
2656
2810
|
if (!extraHosts && !eventCalendar && !siteCare && folded === resolved) {
|
|
2657
2811
|
return resolved;
|
|
2658
2812
|
}
|
|
@@ -2693,7 +2847,7 @@ function resolvePlan(org) {
|
|
|
2693
2847
|
* quota each names gains its per-plan figure per unit, and its features
|
|
2694
2848
|
* switch on. Returns the input object untouched when nothing applies, so a
|
|
2695
2849
|
* caller can tell "nothing folded" from "folded to the same numbers".
|
|
2696
|
-
*/ function foldPluginSeatAddons(resolved, purchased, plan) {
|
|
2850
|
+
*/ function foldPluginSeatAddons(resolved, purchased, plan, org) {
|
|
2697
2851
|
let out = resolved;
|
|
2698
2852
|
for (const addon of listPluginSeatAddons()){
|
|
2699
2853
|
var _addon_features;
|
|
@@ -2703,8 +2857,9 @@ function resolvePlan(org) {
|
|
|
2703
2857
|
features: _extends({}, out.features)
|
|
2704
2858
|
});
|
|
2705
2859
|
if (addon.quota) {
|
|
2706
|
-
var
|
|
2707
|
-
|
|
2860
|
+
var _ref, _bag_addon_quota_key;
|
|
2861
|
+
var _addon_quota_perUnitByPlan;
|
|
2862
|
+
const perUnit = addon.quota.perUnit ? addon.quota.perUnit(org, plan) : (_ref = (_addon_quota_perUnitByPlan = addon.quota.perUnitByPlan) == null ? void 0 : _addon_quota_perUnitByPlan[plan]) != null ? _ref : 0;
|
|
2708
2863
|
const bag = next;
|
|
2709
2864
|
const current = Number((_bag_addon_quota_key = bag[addon.quota.key]) != null ? _bag_addon_quota_key : 0);
|
|
2710
2865
|
bag[addon.quota.key] = (Number.isFinite(current) ? current : 0) + perUnit * units;
|