@developer_tribe/react-builder 1.2.27 → 1.2.29
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/assets/samples/getSamples.d.ts +0 -3
- package/dist/build-components/BIcon/BIconProps.generated.d.ts +1 -2
- package/dist/build-components/CountDown/CountDownProps.generated.d.ts +2 -1
- package/dist/build-components/OnboardFooter/OnboardFooterProps.generated.d.ts +1 -2
- package/dist/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.d.ts +1 -2
- package/dist/build-components/OnboardTitle/OnboardTitleProps.generated.d.ts +1 -2
- package/dist/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.d.ts +1 -2
- package/dist/build-components/PaywallOptions/usePaywallOptionParamsFactory.d.ts +1 -1
- package/dist/build-components/PriceTag/PriceTag.d.ts +5 -0
- package/dist/build-components/PriceTag/PriceTagProps.generated.d.ts +63 -0
- package/dist/build-components/Pricing/Pricing.d.ts +5 -0
- package/dist/build-components/Pricing/PricingProps.generated.d.ts +59 -0
- package/dist/build-components/Promo/Promo.d.ts +5 -0
- package/dist/build-components/Promo/PromoProps.generated.d.ts +59 -0
- package/dist/build-components/Text/TextProps.generated.d.ts +1 -2
- package/dist/build-components/index.d.ts +4 -1
- package/dist/build-components/patterns.generated.d.ts +1405 -202
- package/dist/components/BuilderProvider.d.ts +5 -3
- package/dist/components/ParamsProvider.d.ts +16 -8
- package/dist/hooks/useSyncHtmlThemeClass.d.ts +1 -1
- package/dist/index.cjs.js +4 -4
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +16 -3
- package/dist/index.esm.js +4 -4
- package/dist/index.esm.js.map +1 -1
- package/dist/index.web.cjs.js +4 -4
- package/dist/index.web.cjs.js.map +1 -1
- package/dist/index.web.esm.js +4 -4
- package/dist/index.web.esm.js.map +1 -1
- package/dist/logger.d.ts +18 -0
- package/dist/modals/InspectModal.d.ts +5 -0
- package/dist/modals/index.d.ts +1 -1
- package/dist/pages/ProjectPage.d.ts +3 -3
- package/dist/paywall/hooks/useCalculateLocalizedPrice.d.ts +4 -2
- package/dist/paywall/hooks/useDiscountRate.d.ts +3 -2
- package/dist/paywall/types/paywall-types.d.ts +7 -32
- package/dist/product-base/buildPaywallLocalizationParams.d.ts +16 -0
- package/dist/product-base/calculations.d.ts +29 -0
- package/dist/product-base/extractAndroidParams.d.ts +24 -0
- package/dist/product-base/extractIOSParams.d.ts +24 -0
- package/dist/product-base/index.d.ts +51 -0
- package/dist/product-base/periodLocalizationKeys.d.ts +44 -0
- package/dist/product-base/types.d.ts +155 -0
- package/dist/product-base/usePaywallLocalizationParams.d.ts +29 -0
- package/dist/store.d.ts +7 -1
- package/dist/styles.css +1 -1
- package/dist/types/PreviewConfig.d.ts +10 -16
- package/dist/utils/extractTextStyle/extractTextStyle.d.ts +2 -2
- package/dist/utils/extractTextStyle/extractTextStyleNative.d.ts +2 -2
- package/dist/utils/replaceLocalizationParams.d.ts +1 -1
- package/package.json +2 -2
- package/scripts/migrate-samples-to-current.ts +3 -3
- package/scripts/prebuild/utils/validateAllComponentsOrThrow.js +28 -12
- package/src/DeviceMockFrame.tsx +15 -10
- package/src/assets/meta.json +1 -1
- package/src/assets/samples/carousel-sample.json +6 -5
- package/src/assets/samples/getSamples.ts +16 -49
- package/src/assets/samples/paywall-1.json +64 -22
- package/src/assets/samples/paywall-2.json +0 -15
- package/src/assets/samples/paywall-app-delete-offer.json +0 -15
- package/src/assets/samples/paywall-app-open-offer.json +0 -15
- package/src/assets/samples/paywall-back-offer.json +0 -15
- package/src/assets/samples/paywall-notification-offer.json +0 -15
- package/src/assets/samples/simple-1.json +1 -16
- package/src/assets/samples/simple-2.json +0 -15
- package/src/assets/samples/unmigrated-builder-1.1.1.json +0 -3
- package/src/assets/samples/unmigrated-builder1.json +0 -3
- package/src/assets/samples/unvalidated-builder1.json +0 -3
- package/src/assets/samples/unvalidated-crash1.json +0 -3
- package/src/assets/samples/unvalidated-crashcomponent1.json +0 -3
- package/src/assets/samples/vpn-onboard-1.json +1 -34
- package/src/assets/samples/vpn-onboard-2.json +1 -34
- package/src/assets/samples/vpn-onboard-3.json +1 -42
- package/src/assets/samples/vpn-onboard-4.json +0 -73
- package/src/assets/samples/vpn-onboard-5.json +0 -73
- package/src/assets/samples/vpn-onboard-6.json +0 -73
- package/src/assets/samples/vpn-onboard-7.json +529 -0
- package/src/attribute-analyser/style/native/useExtractImageStyle.ts +1 -4
- package/src/attribute-analyser/style/native/useExtractTextStyle.ts +3 -12
- package/src/attribute-analyser/style/native/useExtractViewStyle.ts +1 -4
- package/src/attribute-analyser/style/web/useExtractImageStyle.ts +1 -4
- package/src/attribute-analyser/style/web/useExtractTextStyle.ts +3 -12
- package/src/attribute-analyser/style/web/useExtractViewStyle.ts +1 -4
- package/src/attributes-editor/useAttributesEditorModel.ts +5 -52
- package/src/build-components/BIcon/BIconProps.generated.ts +1 -2
- package/src/build-components/CarouselDots/CarouselDots.tsx +6 -13
- package/src/build-components/CountDown/CountDownProps.generated.ts +2 -1
- package/src/build-components/NavigationBarColor/NavigationBarColor.tsx +2 -2
- package/src/build-components/OnboardButton/OnboardButton.tsx +1 -2
- package/src/build-components/OnboardDot/OnboardDot.tsx +6 -18
- package/src/build-components/OnboardFooter/OnboardFooter.tsx +5 -3
- package/src/build-components/OnboardFooter/OnboardFooterProps.generated.ts +1 -2
- package/src/build-components/OnboardFooter/pattern.json +1 -1
- package/src/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.ts +1 -2
- package/src/build-components/OnboardTitle/OnboardTitleProps.generated.ts +1 -2
- package/src/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.ts +1 -2
- package/src/build-components/PaywallOptions/PaywallOptions.tsx +3 -3
- package/src/build-components/PaywallOptions/usePaywallOptionParamsFactory.ts +26 -13
- package/src/build-components/PaywallProvider/PaywallProvider.tsx +51 -12
- package/src/build-components/PriceTag/PriceTag.tsx +25 -0
- package/src/build-components/PriceTag/PriceTagProps.generated.ts +83 -0
- package/src/build-components/PriceTag/pattern.json +53 -0
- package/src/build-components/Pricing/Pricing.tsx +13 -0
- package/src/build-components/Pricing/PricingProps.generated.ts +76 -0
- package/src/build-components/Pricing/pattern.json +25 -0
- package/src/build-components/Promo/Promo.tsx +13 -0
- package/src/build-components/Promo/PromoProps.generated.ts +76 -0
- package/src/build-components/Promo/pattern.json +25 -0
- package/src/build-components/RadioButton/RadioButton.tsx +3 -5
- package/src/build-components/RenderNode.generated.tsx +15 -0
- package/src/build-components/StatusBarColor/StatusBarColor.tsx +2 -2
- package/src/build-components/Text/Text.tsx +12 -5
- package/src/build-components/Text/TextProps.generated.ts +1 -2
- package/src/build-components/Text/pattern.json +3 -2
- package/src/build-components/index.ts +15 -0
- package/src/build-components/patterns.generated.ts +1454 -181
- package/src/components/BottomBar.tsx +42 -39
- package/src/components/BuilderProvider.tsx +41 -14
- package/src/components/LocalizationParamsProvider.tsx +1 -1
- package/src/components/ParamsProvider.tsx +36 -11
- package/src/hooks/useLocalize.ts +7 -4
- package/src/hooks/useParams.ts +1 -1
- package/src/hooks/useSyncHtmlThemeClass.ts +2 -2
- package/src/index.ts +54 -8
- package/src/logger.ts +39 -0
- package/src/modals/InspectModal.tsx +331 -0
- package/src/modals/ProductPresetsModal.tsx +7 -14
- package/src/modals/index.ts +1 -1
- package/src/pages/DebugJsonPage.tsx +9 -22
- package/src/pages/ProjectDebug.tsx +1 -1
- package/src/pages/ProjectPage.tsx +29 -11
- package/src/pages/tabs/SideTool.tsx +28 -104
- package/src/paywall/hooks/useCalculateLocalizedPrice.ts +8 -3
- package/src/paywall/hooks/useDiscountRate.ts +11 -3
- package/src/paywall/types/paywall-types.ts +7 -38
- package/src/product-base/buildPaywallLocalizationParams.ts +100 -0
- package/src/product-base/calculations.ts +93 -0
- package/src/product-base/extractAndroidParams.ts +207 -0
- package/src/product-base/extractIOSParams.ts +199 -0
- package/src/product-base/index.ts +64 -0
- package/src/product-base/mockProducts.json +489 -0
- package/src/product-base/periodLocalizationKeys.ts +114 -0
- package/src/product-base/types.ts +183 -0
- package/src/product-base/usePaywallLocalizationParams.ts +61 -0
- package/src/store.ts +18 -1
- package/src/styles/index.scss +1 -0
- package/src/styles/modals/_inspect-modal.scss +155 -0
- package/src/types/PreviewConfig.ts +157 -16
- package/src/utils/extractTextStyle/extractTextStyle.ts +14 -6
- package/src/utils/extractTextStyle/extractTextStyleNative.ts +8 -6
- package/src/utils/logRenderStore.ts +6 -10
- package/src/utils/parseColor.ts +0 -1
- package/src/utils/replaceLocalizationParams.ts +8 -4
- package/dist/modals/ScreenColorsModal.d.ts +0 -8
- package/src/assets/products.json +0 -98
- package/src/modals/ScreenColorsModal.tsx +0 -121
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { convertIOSPeriodUnit } from './periodLocalizationKeys';
|
|
2
|
+
import { iapLogger } from '../logger';
|
|
3
|
+
import {
|
|
4
|
+
calculateDiscount,
|
|
5
|
+
calculatePricePerMonth,
|
|
6
|
+
calculatePricePerYear,
|
|
7
|
+
} from './calculations';
|
|
8
|
+
import type { Product, IOSDiscount, IOSIntroductoryPrice } from './types';
|
|
9
|
+
|
|
10
|
+
export interface IOSParams {
|
|
11
|
+
price: string;
|
|
12
|
+
promoPrice: string;
|
|
13
|
+
currency: string;
|
|
14
|
+
localizedPrice: string;
|
|
15
|
+
period: string;
|
|
16
|
+
periodValue: string;
|
|
17
|
+
periodType: string;
|
|
18
|
+
promoPeriod: string;
|
|
19
|
+
promoCycles: string;
|
|
20
|
+
promoPeriodUnit: string;
|
|
21
|
+
hasTrial: string;
|
|
22
|
+
trialPeriod: string;
|
|
23
|
+
trialPeriodUnit: string;
|
|
24
|
+
discountPercentage: string;
|
|
25
|
+
pricePerMonth: string;
|
|
26
|
+
pricePerYear: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function isFreeTrialIntro(introPrice: IOSIntroductoryPrice): boolean {
|
|
30
|
+
return (
|
|
31
|
+
introPrice.type === 'free_trial' ||
|
|
32
|
+
parseFloat(introPrice.price || introPrice.priceIOS || '0') === 0
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function extractPromoCyclesAndPeriod(
|
|
37
|
+
cycles: number,
|
|
38
|
+
periodUnit: string,
|
|
39
|
+
): { promoPeriod: string; promoCycles: string; promoPeriodUnit: string } {
|
|
40
|
+
return {
|
|
41
|
+
promoPeriod: `${cycles} ${periodUnit}${cycles > 1 ? 's' : ''}`,
|
|
42
|
+
promoCycles: String(cycles),
|
|
43
|
+
promoPeriodUnit: periodUnit,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* iOS product'tan params'ları extract eder
|
|
49
|
+
* introductoryPrice ve discounts'tan trial/promo bilgilerini parse eder
|
|
50
|
+
*/
|
|
51
|
+
export function extractIOSParams(
|
|
52
|
+
product: Product,
|
|
53
|
+
offerId?: string,
|
|
54
|
+
): IOSParams {
|
|
55
|
+
try {
|
|
56
|
+
const price = String(product.price || product.localizedPrice || '').replace(
|
|
57
|
+
/[^0-9.]/g,
|
|
58
|
+
'',
|
|
59
|
+
);
|
|
60
|
+
const currency = product.currency || product.currencyCode || '';
|
|
61
|
+
const localizedPrice = product.localizedPrice || '';
|
|
62
|
+
|
|
63
|
+
const periodUnit = convertIOSPeriodUnit(
|
|
64
|
+
product.subscriptionPeriodUnitIOS || 'MONTH',
|
|
65
|
+
);
|
|
66
|
+
const periodValue = String(product.subscriptionPeriodNumberIOS || 1);
|
|
67
|
+
const periodType = `${periodValue} ${periodUnit}${parseInt(periodValue, 10) > 1 ? 's' : ''}`;
|
|
68
|
+
|
|
69
|
+
const introPrice =
|
|
70
|
+
product.introductoryPrice || product.introductoryPriceIOS;
|
|
71
|
+
const hasIntro = !!introPrice;
|
|
72
|
+
const isTrial = hasIntro && isFreeTrialIntro(introPrice);
|
|
73
|
+
|
|
74
|
+
let hasTrial = 'false';
|
|
75
|
+
let trialPeriod = '';
|
|
76
|
+
let trialPeriodUnit = '';
|
|
77
|
+
let promoPrice = '';
|
|
78
|
+
let promoPeriod = '';
|
|
79
|
+
let promoCycles = '';
|
|
80
|
+
let promoPeriodUnit = '';
|
|
81
|
+
|
|
82
|
+
if (isTrial) {
|
|
83
|
+
hasTrial = 'true';
|
|
84
|
+
trialPeriod = String(
|
|
85
|
+
introPrice.subscriptionPeriodNumberIOS ||
|
|
86
|
+
introPrice.numberOfPeriods ||
|
|
87
|
+
7,
|
|
88
|
+
);
|
|
89
|
+
trialPeriodUnit = convertIOSPeriodUnit(
|
|
90
|
+
introPrice.subscriptionPeriodUnitIOS ||
|
|
91
|
+
introPrice.subscriptionPeriod ||
|
|
92
|
+
'DAY',
|
|
93
|
+
);
|
|
94
|
+
} else if (hasIntro) {
|
|
95
|
+
promoPrice = String(
|
|
96
|
+
introPrice.price || introPrice.priceIOS || '',
|
|
97
|
+
).replace(/[^0-9.]/g, '');
|
|
98
|
+
const cycles = introPrice.numberOfPeriods || 1;
|
|
99
|
+
const unit = convertIOSPeriodUnit(
|
|
100
|
+
introPrice.subscriptionPeriodUnitIOS ||
|
|
101
|
+
introPrice.subscriptionPeriod ||
|
|
102
|
+
'MONTH',
|
|
103
|
+
);
|
|
104
|
+
const extracted = extractPromoCyclesAndPeriod(cycles, unit);
|
|
105
|
+
promoPeriod = extracted.promoPeriod;
|
|
106
|
+
promoCycles = extracted.promoCycles;
|
|
107
|
+
promoPeriodUnit = extracted.promoPeriodUnit;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Promotional offers (discounts) - offerId ile eşleşen discount
|
|
111
|
+
if (offerId && product.discounts) {
|
|
112
|
+
const discount = product.discounts.find(
|
|
113
|
+
(d: IOSDiscount) => d.identifier === offerId,
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
if (discount) {
|
|
117
|
+
promoPrice = String(discount.price || '').replace(/[^0-9.]/g, '');
|
|
118
|
+
const cycles = discount.numberOfPeriods || 1;
|
|
119
|
+
const unit = convertIOSPeriodUnit(
|
|
120
|
+
discount.subscriptionPeriod || 'MONTH',
|
|
121
|
+
);
|
|
122
|
+
const extracted = extractPromoCyclesAndPeriod(cycles, unit);
|
|
123
|
+
promoPeriod = extracted.promoPeriod;
|
|
124
|
+
promoCycles = extracted.promoCycles;
|
|
125
|
+
promoPeriodUnit = extracted.promoPeriodUnit;
|
|
126
|
+
} else {
|
|
127
|
+
iapLogger.error(
|
|
128
|
+
['extractIOSParams'],
|
|
129
|
+
'Requested offer not found in discounts',
|
|
130
|
+
{
|
|
131
|
+
productId: product.id || product.productId,
|
|
132
|
+
requestedOfferId: offerId,
|
|
133
|
+
availableDiscounts: product.discounts.map(
|
|
134
|
+
(d: IOSDiscount) => d.identifier,
|
|
135
|
+
),
|
|
136
|
+
},
|
|
137
|
+
{ remote: true },
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const discountPercentage = calculateDiscount(price, promoPrice);
|
|
143
|
+
const priceNum = parseFloat(price);
|
|
144
|
+
const pricePerMonth = calculatePricePerMonth(priceNum, periodUnit);
|
|
145
|
+
const pricePerYear = calculatePricePerYear(priceNum, periodUnit);
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
price,
|
|
149
|
+
promoPrice,
|
|
150
|
+
currency,
|
|
151
|
+
localizedPrice,
|
|
152
|
+
period: periodUnit,
|
|
153
|
+
periodValue,
|
|
154
|
+
periodType,
|
|
155
|
+
promoPeriod,
|
|
156
|
+
promoCycles,
|
|
157
|
+
promoPeriodUnit,
|
|
158
|
+
hasTrial,
|
|
159
|
+
trialPeriod,
|
|
160
|
+
trialPeriodUnit,
|
|
161
|
+
discountPercentage,
|
|
162
|
+
pricePerMonth,
|
|
163
|
+
pricePerYear,
|
|
164
|
+
};
|
|
165
|
+
} catch (error) {
|
|
166
|
+
iapLogger.error(
|
|
167
|
+
['extractIOSParams'],
|
|
168
|
+
'Failed to extract iOS params',
|
|
169
|
+
{
|
|
170
|
+
productId: product?.id || product?.productId,
|
|
171
|
+
error: error instanceof Error ? error.message : String(error),
|
|
172
|
+
},
|
|
173
|
+
{ remote: true },
|
|
174
|
+
);
|
|
175
|
+
return getEmptyParams();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** Boş params döner (fallback) */
|
|
180
|
+
function getEmptyParams(): IOSParams {
|
|
181
|
+
return {
|
|
182
|
+
price: '',
|
|
183
|
+
promoPrice: '',
|
|
184
|
+
currency: '',
|
|
185
|
+
localizedPrice: '',
|
|
186
|
+
period: 'month',
|
|
187
|
+
periodValue: '1',
|
|
188
|
+
periodType: '1 month',
|
|
189
|
+
promoPeriod: '',
|
|
190
|
+
promoCycles: '',
|
|
191
|
+
promoPeriodUnit: '',
|
|
192
|
+
hasTrial: 'false',
|
|
193
|
+
trialPeriod: '',
|
|
194
|
+
trialPeriodUnit: '',
|
|
195
|
+
discountPercentage: '',
|
|
196
|
+
pricePerMonth: '',
|
|
197
|
+
pricePerYear: '',
|
|
198
|
+
};
|
|
199
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Product base — centralized product utilities for paywall.
|
|
3
|
+
*
|
|
4
|
+
* This module is the single source of truth for product extraction, calculation
|
|
5
|
+
* and localization logic. It is consumed by:
|
|
6
|
+
* - This library's own web builder (PaywallProvider, ProductPresetsModal)
|
|
7
|
+
* - The core React Native project via `@developer_tribe/react-builder` exports
|
|
8
|
+
*
|
|
9
|
+
* Everything here is RN-safe (no DOM, no SCSS, no window/document).
|
|
10
|
+
*
|
|
11
|
+
* Includes:
|
|
12
|
+
* - types.ts : Product, PricingPhase, SubscriptionOffer, IOSDiscount, etc.
|
|
13
|
+
* - calculations.ts : extractPrice, calculateDiscount, pricePerMonth/Year
|
|
14
|
+
* - periodLocalizationKeys.ts : PERIOD_LOCALIZATION_KEYS, parseBillingPeriod, convertIOSPeriodUnit
|
|
15
|
+
* - extractAndroidParams.ts : Android pricingPhases extraction (trial, promo, regular)
|
|
16
|
+
* - extractIOSParams.ts : iOS introductoryPrice/discounts extraction
|
|
17
|
+
* - buildPaywallLocalizationParams.ts : Pure function — platform injected from outside
|
|
18
|
+
* - usePaywallLocalizationParams.ts : Generic React hook — all deps via config param
|
|
19
|
+
* - mockProducts.json : Mock product data for testing (Android + iOS)
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
export * from './types';
|
|
23
|
+
export * from './calculations';
|
|
24
|
+
export * from './periodLocalizationKeys';
|
|
25
|
+
export * from './extractAndroidParams';
|
|
26
|
+
export * from './extractIOSParams';
|
|
27
|
+
export * from './buildPaywallLocalizationParams';
|
|
28
|
+
export * from './usePaywallLocalizationParams';
|
|
29
|
+
|
|
30
|
+
/* ── Mock Products ── */
|
|
31
|
+
|
|
32
|
+
import presetsJson from './mockProducts.json';
|
|
33
|
+
import type { Product } from './types';
|
|
34
|
+
|
|
35
|
+
/** Preset map: preset key → product array. */
|
|
36
|
+
export type MockProductPresets = Record<string, Product[]>;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Returns a deep-copy of all mock product presets.
|
|
40
|
+
*
|
|
41
|
+
* Use this instead of importing `mockProducts.json` directly so that:
|
|
42
|
+
* 1. Consumers don't couple to a JSON file path.
|
|
43
|
+
* 2. Each call returns a fresh copy (safe to mutate).
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* import { getMockProducts } from '@developer_tribe/react-builder';
|
|
47
|
+
* const presets = getMockProducts(); // { 'preset-1': [...], ... }
|
|
48
|
+
*/
|
|
49
|
+
export function getMockProducts(): MockProductPresets {
|
|
50
|
+
return JSON.parse(JSON.stringify(presetsJson)) as MockProductPresets;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Returns the product list for a specific preset key (deep-copied).
|
|
55
|
+
* Returns an empty array if the key doesn't exist.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* import { getMockProductsByPreset } from '@developer_tribe/react-builder';
|
|
59
|
+
* const products = getMockProductsByPreset('preset-1');
|
|
60
|
+
*/
|
|
61
|
+
export function getMockProductsByPreset(presetKey: string): Product[] {
|
|
62
|
+
const all = getMockProducts();
|
|
63
|
+
return all[presetKey] ?? [];
|
|
64
|
+
}
|