@burdenoff/website-sdk 2026.728.1 → 2026.728.3
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/components/pricing.d.mts +29 -1
- package/dist/components/pricing.d.ts +29 -1
- package/dist/components/pricing.js +15 -13
- package/dist/components/pricing.js.map +1 -1
- package/dist/components/pricing.mjs +15 -14
- package/dist/components/pricing.mjs.map +1 -1
- package/dist/index.js +14 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +14 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -35,6 +35,7 @@ interface PlanCard {
|
|
|
35
35
|
features: Array<{
|
|
36
36
|
id: string;
|
|
37
37
|
quotaId?: string | null;
|
|
38
|
+
context?: unknown;
|
|
38
39
|
quota?: {
|
|
39
40
|
id: string;
|
|
40
41
|
name: string;
|
|
@@ -239,6 +240,33 @@ declare function resolveEnterprisePlans<T extends {
|
|
|
239
240
|
}): Array<T | {
|
|
240
241
|
name: string;
|
|
241
242
|
}>;
|
|
243
|
+
/**
|
|
244
|
+
* Transform a plan feature (quota link) into a human-readable string.
|
|
245
|
+
*
|
|
246
|
+
* BOFF-4206: the per-PLAN quantity lives on the SubscriptionFeature's own
|
|
247
|
+
* `context` (e.g. `{ quantity: 250, unit: 'profiles' }`) — `quota.limits` is
|
|
248
|
+
* the SHARED Quota row's value, set once at quota-creation time and
|
|
249
|
+
* IDENTICAL for every plan that links that quota. Reading `quota.limits`
|
|
250
|
+
* here made every tier's card show the same numbers: live on TimeCampus's
|
|
251
|
+
* /pricing, Starter/Growth/Business all rendered Free's "1 Projects" and "2
|
|
252
|
+
* Admin Seats" instead of their real, higher, per-tier limits. Prefer the
|
|
253
|
+
* per-feature `context.quantity`; fall back to `quota.limits.value` only
|
|
254
|
+
* when a feature genuinely carries no context (legacy rows seeded before
|
|
255
|
+
* this convention, or a quota linked without a context payload).
|
|
256
|
+
*
|
|
257
|
+
* Exported (pure, no React/hooks) so this exact precedence is unit-testable
|
|
258
|
+
* without a DOM/render harness, matching `splitPlansByAudience` /
|
|
259
|
+
* `resolveEnterprisePlans` above.
|
|
260
|
+
*/
|
|
261
|
+
declare function transformFeatureToLabel(feature: {
|
|
262
|
+
quotaId?: string | null;
|
|
263
|
+
context?: unknown;
|
|
264
|
+
quota?: {
|
|
265
|
+
id: string;
|
|
266
|
+
name: string;
|
|
267
|
+
limits?: unknown;
|
|
268
|
+
} | null;
|
|
269
|
+
}): string;
|
|
242
270
|
/**
|
|
243
271
|
* Pricing Section Component - Embeddable
|
|
244
272
|
*/
|
|
@@ -248,4 +276,4 @@ declare function PricingSection(props: PricingProps): react_jsx_runtime.JSX.Elem
|
|
|
248
276
|
*/
|
|
249
277
|
declare function PricingPage(props: PricingProps): react_jsx_runtime.JSX.Element;
|
|
250
278
|
|
|
251
|
-
export { type PlanCard, PricingPage, type PricingProps, PricingSection, resolveEnterprisePlans, splitPlansByAudience };
|
|
279
|
+
export { type PlanCard, PricingPage, type PricingProps, PricingSection, resolveEnterprisePlans, splitPlansByAudience, transformFeatureToLabel };
|
|
@@ -35,6 +35,7 @@ interface PlanCard {
|
|
|
35
35
|
features: Array<{
|
|
36
36
|
id: string;
|
|
37
37
|
quotaId?: string | null;
|
|
38
|
+
context?: unknown;
|
|
38
39
|
quota?: {
|
|
39
40
|
id: string;
|
|
40
41
|
name: string;
|
|
@@ -239,6 +240,33 @@ declare function resolveEnterprisePlans<T extends {
|
|
|
239
240
|
}): Array<T | {
|
|
240
241
|
name: string;
|
|
241
242
|
}>;
|
|
243
|
+
/**
|
|
244
|
+
* Transform a plan feature (quota link) into a human-readable string.
|
|
245
|
+
*
|
|
246
|
+
* BOFF-4206: the per-PLAN quantity lives on the SubscriptionFeature's own
|
|
247
|
+
* `context` (e.g. `{ quantity: 250, unit: 'profiles' }`) — `quota.limits` is
|
|
248
|
+
* the SHARED Quota row's value, set once at quota-creation time and
|
|
249
|
+
* IDENTICAL for every plan that links that quota. Reading `quota.limits`
|
|
250
|
+
* here made every tier's card show the same numbers: live on TimeCampus's
|
|
251
|
+
* /pricing, Starter/Growth/Business all rendered Free's "1 Projects" and "2
|
|
252
|
+
* Admin Seats" instead of their real, higher, per-tier limits. Prefer the
|
|
253
|
+
* per-feature `context.quantity`; fall back to `quota.limits.value` only
|
|
254
|
+
* when a feature genuinely carries no context (legacy rows seeded before
|
|
255
|
+
* this convention, or a quota linked without a context payload).
|
|
256
|
+
*
|
|
257
|
+
* Exported (pure, no React/hooks) so this exact precedence is unit-testable
|
|
258
|
+
* without a DOM/render harness, matching `splitPlansByAudience` /
|
|
259
|
+
* `resolveEnterprisePlans` above.
|
|
260
|
+
*/
|
|
261
|
+
declare function transformFeatureToLabel(feature: {
|
|
262
|
+
quotaId?: string | null;
|
|
263
|
+
context?: unknown;
|
|
264
|
+
quota?: {
|
|
265
|
+
id: string;
|
|
266
|
+
name: string;
|
|
267
|
+
limits?: unknown;
|
|
268
|
+
} | null;
|
|
269
|
+
}): string;
|
|
242
270
|
/**
|
|
243
271
|
* Pricing Section Component - Embeddable
|
|
244
272
|
*/
|
|
@@ -248,4 +276,4 @@ declare function PricingSection(props: PricingProps): react_jsx_runtime.JSX.Elem
|
|
|
248
276
|
*/
|
|
249
277
|
declare function PricingPage(props: PricingProps): react_jsx_runtime.JSX.Element;
|
|
250
278
|
|
|
251
|
-
export { type PlanCard, PricingPage, type PricingProps, PricingSection, resolveEnterprisePlans, splitPlansByAudience };
|
|
279
|
+
export { type PlanCard, PricingPage, type PricingProps, PricingSection, resolveEnterprisePlans, splitPlansByAudience, transformFeatureToLabel };
|
|
@@ -334,6 +334,7 @@ var GET_PLANS_QUERY = `
|
|
|
334
334
|
features {
|
|
335
335
|
id
|
|
336
336
|
quotaId
|
|
337
|
+
context
|
|
337
338
|
quota {
|
|
338
339
|
id
|
|
339
340
|
name
|
|
@@ -446,27 +447,27 @@ function humanizeQuotaName(name) {
|
|
|
446
447
|
const resource = parts.length >= 3 ? parts[parts.length - 2] : parts[parts.length - 1];
|
|
447
448
|
return resource.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
448
449
|
}
|
|
449
|
-
function
|
|
450
|
+
function transformFeatureToLabel(feature) {
|
|
451
|
+
const quota = feature.quota;
|
|
452
|
+
if (!quota) return "";
|
|
450
453
|
const { name, limits } = quota;
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
const
|
|
455
|
-
const
|
|
456
|
-
const
|
|
457
|
-
|
|
458
|
-
const description = limitsObj.description;
|
|
459
|
-
if (typeof description === "string" && description) {
|
|
454
|
+
const featureContext = feature.context && typeof feature.context === "object" ? feature.context : null;
|
|
455
|
+
const limitsObj = limits && typeof limits === "object" ? limits : null;
|
|
456
|
+
const value = typeof featureContext?.quantity === "number" ? featureContext.quantity : typeof limitsObj?.value === "number" ? limitsObj.value : void 0;
|
|
457
|
+
const unit = typeof featureContext?.unit === "string" && featureContext.unit || typeof limitsObj?.unit === "string" && limitsObj.unit || void 0;
|
|
458
|
+
const description = typeof featureContext?.description === "string" && featureContext.description || typeof limitsObj?.description === "string" && limitsObj.description || void 0;
|
|
459
|
+
const type = limitsObj?.type;
|
|
460
|
+
if (description) {
|
|
460
461
|
if (type === "number" && typeof value === "number") {
|
|
461
462
|
return `${value.toLocaleString()} ${description}`;
|
|
462
463
|
}
|
|
463
464
|
return description;
|
|
464
465
|
}
|
|
465
|
-
if (
|
|
466
|
+
if (unit) {
|
|
466
467
|
if (typeof value === "number") {
|
|
467
468
|
return `${value.toLocaleString()} ${unit}`;
|
|
468
469
|
}
|
|
469
|
-
return
|
|
470
|
+
return unit;
|
|
470
471
|
}
|
|
471
472
|
const label = humanizeQuotaName(name);
|
|
472
473
|
if (type === "boolean") {
|
|
@@ -485,7 +486,7 @@ function extractDisplayFeatures(features, planName, fallbackFeatures) {
|
|
|
485
486
|
return tierFeatures;
|
|
486
487
|
}
|
|
487
488
|
}
|
|
488
|
-
const quotaFeatures = features.filter((f) => f.quota).map((f) =>
|
|
489
|
+
const quotaFeatures = features.filter((f) => f.quota).map((f) => transformFeatureToLabel(f));
|
|
489
490
|
if (quotaFeatures.length > 0) {
|
|
490
491
|
return quotaFeatures;
|
|
491
492
|
}
|
|
@@ -884,5 +885,6 @@ exports.PricingPage = PricingPage;
|
|
|
884
885
|
exports.PricingSection = PricingSection;
|
|
885
886
|
exports.resolveEnterprisePlans = resolveEnterprisePlans;
|
|
886
887
|
exports.splitPlansByAudience = splitPlansByAudience;
|
|
888
|
+
exports.transformFeatureToLabel = transformFeatureToLabel;
|
|
887
889
|
//# sourceMappingURL=pricing.js.map
|
|
888
890
|
//# sourceMappingURL=pricing.js.map
|