@wix/pricing-plans-site-api 0.0.0-stage → 1.0.0

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/README.md CHANGED
@@ -1,3 +1,61 @@
1
- # Temporary Holding Version
1
+ # @wix/pricing-plans-site-api
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Lets other verticals send site visitors to Pricing Plans pages from their own React components. It replaces the legacy Pricing Plans public API (`getPricingPlansPublicAPI` from `@wix/pricing-plans-tpa-api`).
4
+
5
+ The site can run either the legacy Pricing Plans app or the new Builder app. The hook works out which one is installed and calls that app's navigation, so the vertical's code is the same for both.
6
+
7
+ ## Usage
8
+
9
+ ```tsx
10
+ import { usePricingPlansSiteApi } from '@wix/pricing-plans-site-api';
11
+
12
+ function BuyPlanButton({ planId }: { planId: string }) {
13
+ const { navigateToPlanPage } = usePricingPlansSiteApi();
14
+
15
+ return <button onClick={() => navigateToPlanPage({ planId })}>Buy plan</button>;
16
+ }
17
+ ```
18
+
19
+ Use the hook inside a site component or context provider, and add the site services it uses to the extension's `serviceDependencies`:
20
+
21
+ ```ts
22
+ resources: {
23
+ client: {
24
+ componentUrl,
25
+ dependencies: {
26
+ serviceDependencies: [
27
+ '@wix/site-service-pages',
28
+ '@wix/site-service-url',
29
+ '@wix/site-service-router',
30
+ '@wix/viewer-service-router',
31
+ '@wix/site-service-public-api-caller',
32
+ ],
33
+ },
34
+ },
35
+ },
36
+ ```
37
+
38
+ The hook navigates with `@wix/site-service-router`. Live sites on Thunderbolt releases from before 2026-10-08 don't provide that service yet, so the hook falls back to the older `@wix/viewer-service-router`. List both until the new one has rolled out everywhere.
39
+
40
+ ## API
41
+
42
+ `usePricingPlansSiteApi()` returns:
43
+
44
+ - `navigateToPricingPage(options?)` opens the Pricing Plans page. `options` take the same fields as the legacy `navigateToPricingPage`: `planIds`, `pricingVariantsByPlanId`, `title`, `subtitle`, `biOptions` and `checkout`.
45
+ - `getPricingPageUrl(options?)` returns the URL of the page `navigateToPricingPage` opens, without navigating. It takes the same `options`.
46
+ - `navigateToPlanPage(options)` starts the purchase of one plan. `options` take the same fields as the legacy `navigateToPlanPage`: `planId`, `pricingVariantId`, `biOptions`, `checkoutFlowId`, `widgetType` and the checkout fields.
47
+
48
+ Each method returns a promise. It rejects when the site doesn't have the page, and the navigation methods also reject when the router doesn't navigate, such as when the site visitor is already on the page.
49
+
50
+ The hook works on any site, even one without Pricing Plans. There, every method rejects with `Pricing Plans is not installed on the site.` and doesn't navigate, so catch the error if your component can render on such sites.
51
+
52
+ ## Builder app support
53
+
54
+ On the legacy app, every option works as before. The Builder app reads fewer options:
55
+
56
+ - `planIds` and `pricingVariantsByPlanId` choose the plans the Plans page shows.
57
+ - `checkout.minStartDate` and `checkout.maxStartDate` limit the start date on the plan customization page. A plan that goes straight to checkout doesn't get them.
58
+ - `checkout.thankYouPage.navigation` sets where the thank you page's continue button goes, and where the plan customization page goes after adding the plan to the cart. A target that isn't on the site is left out.
59
+ - `title`, `subtitle`, `biOptions`, `checkoutFlowId`, `widgetType` and `checkout.thankYouPage.content` aren't supported, and are left out.
60
+
61
+ `navigateToPlanPage` rejects a plan that isn't public, isn't buyable or has no visible pricing variant. On the Builder app it loads the plan and creates the eCommerce cart as the vertical's app, so the app needs permission to read Pricing Plans plans and to manage eCommerce carts.
@@ -0,0 +1,125 @@
1
+ import "@wix/react-component-utils";
2
+ //#region src/types.d.ts
3
+ type BiOptions = {
4
+ referralInfo: string;
5
+ referralId?: string;
6
+ };
7
+ type NavigateToSectionOptions = {
8
+ appDefinitionId: string;
9
+ sectionId: string;
10
+ queryParams?: object;
11
+ state?: string;
12
+ discardRouterPageSuffix?: boolean;
13
+ };
14
+ type NavigationPolicy = {
15
+ type: 'url';
16
+ url: string;
17
+ } | {
18
+ type: 'section';
19
+ options: NavigateToSectionOptions;
20
+ } | {
21
+ type: 'page';
22
+ pageId: string;
23
+ };
24
+ type ThankYouPageOptions = {
25
+ content?: {
26
+ title?: string;
27
+ message?: string;
28
+ cta?: string;
29
+ };
30
+ navigation?: NavigationPolicy;
31
+ };
32
+ type CheckoutOptions = {
33
+ minStartDate?: string;
34
+ maxStartDate?: string;
35
+ thankYouPage?: ThankYouPageOptions;
36
+ };
37
+ type NavigateToPricingPageOptions = {
38
+ planIds?: string[];
39
+ pricingVariantsByPlanId?: Record<string, string[]>;
40
+ title?: string;
41
+ subtitle?: string;
42
+ biOptions?: BiOptions;
43
+ checkout?: CheckoutOptions;
44
+ };
45
+ type NavigateToPlanPageOptions = {
46
+ planId: string;
47
+ pricingVariantId?: string;
48
+ biOptions?: BiOptions;
49
+ checkoutFlowId?: string;
50
+ widgetType?: string;
51
+ } & CheckoutOptions;
52
+ type PricingPlansSiteApi = {
53
+ /**
54
+ * Opens the Pricing Plans page, where site visitors pick a plan.
55
+ *
56
+ * On the legacy app, it accepts every option of the legacy `navigateToPricingPage`. The Builder
57
+ * app only reads `planIds`, `pricingVariantsByPlanId`, `checkout.minStartDate`,
58
+ * `checkout.maxStartDate` and `checkout.thankYouPage.navigation`; it leaves out the rest.
59
+ *
60
+ * @param options Plans to show and checkout settings. Shows the page's own plans when omitted.
61
+ * @returns Resolves once the site visitor is on the pricing page.
62
+ * @throws `Pricing Plans is not installed on the site.` when Pricing Plans isn't installed on the
63
+ * site.
64
+ * @throws When the site has Pricing Plans but no page to show the plans on.
65
+ * @throws When the router doesn't navigate, such as when the site visitor is already on the page.
66
+ */
67
+ navigateToPricingPage(options?: NavigateToPricingPageOptions): Promise<void>;
68
+ /**
69
+ * Builds the URL of the Pricing Plans page, the page {@link navigateToPricingPage} opens, without
70
+ * navigating to it. Use it for links, like a paywall's "See plans" button.
71
+ *
72
+ * Reads the same options as {@link navigateToPricingPage}, on both the legacy and the Builder
73
+ * app.
74
+ *
75
+ * @param options Plans to show and checkout settings. Shows the page's own plans when omitted.
76
+ * @returns The absolute URL of the pricing page.
77
+ * @throws `Pricing Plans is not installed on the site.` when Pricing Plans isn't installed on the
78
+ * site.
79
+ * @throws When the site has Pricing Plans but no page to show the plans on.
80
+ */
81
+ getPricingPageUrl(options?: NavigateToPricingPageOptions): Promise<string>;
82
+ /**
83
+ * Starts the purchase of one plan, like the legacy `navigateToPlanPage`: goes to the plan
84
+ * customization page when the plan has a form or a start date to choose, and to checkout
85
+ * otherwise.
86
+ *
87
+ * Uses the given pricing variant, or the plan's first one when `pricingVariantId` is omitted.
88
+ * The Builder app leaves out `biOptions`, `checkoutFlowId`, `widgetType` and
89
+ * `thankYouPage.content`.
90
+ *
91
+ * @param options Plan to buy and checkout settings.
92
+ * @returns Resolves once the site visitor is on the plan customization page or checkout.
93
+ * @throws `Pricing Plans is not installed on the site.` when Pricing Plans isn't installed on the
94
+ * site.
95
+ * @throws When the plan can't be bought online, or when the site has no page to buy it on.
96
+ * @throws When the router doesn't navigate.
97
+ */
98
+ navigateToPlanPage(options: NavigateToPlanPageOptions): Promise<void>;
99
+ };
100
+ //#endregion
101
+ //#region src/use-pricing-plans-site-api.d.ts
102
+ /**
103
+ * Navigation to Pricing Plans pages that works with both versions of the Pricing Plans app: the
104
+ * legacy app (OOI) and the Builder app. The hook detects which one the site runs and uses its
105
+ * pages, so the calls are the same for both.
106
+ *
107
+ * Calling the hook is safe on any site. When Pricing Plans isn't installed on the site, every method
108
+ * it returns rejects with the error `Pricing Plans is not installed on the site.` and doesn't
109
+ * navigate. The hook treats Pricing Plans as installed when the site has at least one Pricing Plans
110
+ * page.
111
+ *
112
+ * Use it inside a site component or context provider, and list these services in the extension's
113
+ * `serviceDependencies`: `@wix/site-service-pages`, `@wix/site-service-url`,
114
+ * `@wix/site-service-router`, `@wix/viewer-service-router` and
115
+ * `@wix/site-service-public-api-caller`.
116
+ *
117
+ * @example
118
+ * const { navigateToPlanPage } = usePricingPlansSiteApi();
119
+ *
120
+ * <button onClick={() => navigateToPlanPage({ planId })}>Buy plan</button>
121
+ */
122
+ declare function usePricingPlansSiteApi(): PricingPlansSiteApi;
123
+ //#endregion
124
+ export { type BiOptions, type CheckoutOptions, type NavigateToPlanPageOptions, type NavigateToPricingPageOptions, type NavigateToSectionOptions, type NavigationPolicy, type PricingPlansSiteApi, type ThankYouPageOptions, usePricingPlansSiteApi };
125
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,300 @@
1
+ import { usePages } from "@wix/react-component-utils";
2
+ import { useGetService, useService } from "@wix/services-manager-react";
3
+ import { UrlDefinition } from "@wix/site-service-url/definition";
4
+ import { useMemo } from "react";
5
+ import { cartV2 } from "@wix/ecom";
6
+ import { plansV3 } from "@wix/pricing-plans";
7
+ import { defineService } from "@wix/services-definitions";
8
+ import { RouterDefinition } from "@wix/site-service-router/definition";
9
+ //#region src/constants.ts
10
+ const PRICING_PLANS_APP_ID = "1522827f-c56c-a5c9-2ac9-00f9e6ae12d3";
11
+ //#endregion
12
+ //#region src/builder/checkout.ts
13
+ async function loadPublicPlan(planId) {
14
+ const { items } = await plansV3.queryPlans().eq("_id", planId).eq("visibility", "PUBLIC").limit(1).find();
15
+ return items[0];
16
+ }
17
+ async function createCheckoutUrl(planId, pricingVariantId) {
18
+ const cart = await cartV2.createCart({
19
+ cart: { source: { channelType: "WEB" } },
20
+ catalogItems: [{
21
+ quantity: 1,
22
+ catalogReference: {
23
+ appId: PRICING_PLANS_APP_ID,
24
+ catalogItemId: planId,
25
+ options: {
26
+ type: "PLAN",
27
+ planOptions: {
28
+ pricingVariantId,
29
+ membersOnly: false
30
+ }
31
+ }
32
+ }
33
+ }]
34
+ });
35
+ if (!cart?._id) throw new Error("Cart creation did not return an ID");
36
+ const { checkoutUrl } = await cartV2.getCheckoutUrl(cart._id);
37
+ if (!checkoutUrl) throw new Error("Checkout URL was not returned");
38
+ return checkoutUrl;
39
+ }
40
+ //#endregion
41
+ //#region src/builder/plan-purchase.ts
42
+ function planPurchase(plan, pricingVariantId) {
43
+ if (!plan || plan.buyable !== true) return;
44
+ const variants = (plan.pricingVariants ?? []).filter((variant) => Boolean(variant._id) && variant.visible !== false);
45
+ const variant = variants.find(({ _id }) => _id === pricingVariantId) ?? variants[0];
46
+ if (!variant) return;
47
+ const requiresStartDate = plan.startDateSettings ? plan.startDateSettings.type === "DATE_RANGE" : variant.billingTerms?.startType === "CUSTOM";
48
+ return {
49
+ pricingVariantId: variant._id,
50
+ requiresCustomization: Boolean(plan.formId) || requiresStartDate
51
+ };
52
+ }
53
+ //#endregion
54
+ //#region src/url.ts
55
+ function siteHref(siteUrl, path) {
56
+ return `${siteUrl.replace(/\/$/, "")}/${path.replace(/^\//, "")}`;
57
+ }
58
+ function withQuery(url, query) {
59
+ const search = query.toString();
60
+ return search ? `${url}?${search}` : url;
61
+ }
62
+ function queryOf(entries) {
63
+ return new URLSearchParams(entries.filter((entry) => Boolean(entry[1])));
64
+ }
65
+ function encodePricingVariants(pricingVariantsByPlanId) {
66
+ return Object.entries(pricingVariantsByPlanId).filter(([, pricingVariantIds]) => pricingVariantIds.length).map(([planId, pricingVariantIds]) => [planId, ...pricingVariantIds].join(":")).join(",");
67
+ }
68
+ //#endregion
69
+ //#region src/app-pages.ts
70
+ function findAppPage(pages, appPageId) {
71
+ const candidates = Object.values(pages).filter((page) => !page.popup && page.appPageId === appPageId);
72
+ const unowned = candidates.filter((page) => !page.appDefinitionId);
73
+ return candidates.find((page) => page.appDefinitionId === "1522827f-c56c-a5c9-2ac9-00f9e6ae12d3") ?? (unowned.length === 1 ? unowned[0] : void 0);
74
+ }
75
+ function appPageUrl(context, appPageId) {
76
+ const path = findAppPage(context.pages, appPageId) ? context.sectionUrl(PRICING_PLANS_APP_ID, appPageId) : void 0;
77
+ return path ? siteHref(context.siteUrl, path) : void 0;
78
+ }
79
+ //#endregion
80
+ //#region src/builder/return-url.ts
81
+ function returnUrl({ pages, siteUrl, sectionUrl }, navigation) {
82
+ if (!navigation) return;
83
+ switch (navigation.type) {
84
+ case "url": return onSiteUrl(siteUrl, navigation.url);
85
+ case "page": {
86
+ const page = pages[navigation.pageId];
87
+ return page && siteHref(siteUrl, page.path);
88
+ }
89
+ case "section": {
90
+ const { appDefinitionId, sectionId, state, queryParams, discardRouterPageSuffix } = navigation.options;
91
+ const path = sectionUrl(appDefinitionId, sectionId, discardRouterPageSuffix);
92
+ if (!path) return;
93
+ const url = siteHref(siteUrl, state ? `${path.replace(/\/$/, "")}/${state}` : path);
94
+ return queryParams ? withQuery(url, new URLSearchParams({ appSectionParams: JSON.stringify(queryParams) })) : url;
95
+ }
96
+ }
97
+ }
98
+ function onSiteUrl(siteUrl, url) {
99
+ try {
100
+ const site = new URL(siteUrl.endsWith("/") ? siteUrl : `${siteUrl}/`);
101
+ const target = new URL(url.startsWith("/") ? siteHref(siteUrl, url) : url, site);
102
+ const basePath = site.pathname.replace(/\/$/, "");
103
+ if (target.origin === site.origin && !target.username && !target.password && (target.protocol === "https:" || target.protocol === "http:") && (target.pathname === basePath || target.pathname.startsWith(`${basePath}/`))) return target.href;
104
+ } catch {
105
+ return;
106
+ }
107
+ }
108
+ //#endregion
109
+ //#region src/builder/checkout-query.ts
110
+ function checkoutQueryEntries(context, checkout = {}) {
111
+ return [
112
+ ["minStartDate", checkout.minStartDate],
113
+ ["maxStartDate", checkout.maxStartDate],
114
+ ["returnUrl", returnUrl(context, checkout.thankYouPage?.navigation)]
115
+ ];
116
+ }
117
+ //#endregion
118
+ //#region src/builder/plan-page-url.ts
119
+ const BUILDER_PLAN_PAGE_ID = "plan-customization-page";
120
+ function builderPlanPageUrl(context, { planId, pricingVariantId, ...checkout }) {
121
+ const url = appPageUrl(context, BUILDER_PLAN_PAGE_ID);
122
+ if (!url) return;
123
+ return withQuery(url, queryOf([
124
+ ["planId", planId],
125
+ ["pricingVariantId", pricingVariantId],
126
+ ...checkoutQueryEntries(context, checkout)
127
+ ]));
128
+ }
129
+ //#endregion
130
+ //#region src/builder/pricing-page-url.ts
131
+ const BUILDER_PRICING_PAGE_ID = "plans-page";
132
+ function builderPricingPageUrl(context, { planIds, pricingVariantsByPlanId, checkout }) {
133
+ const url = appPageUrl(context, BUILDER_PRICING_PAGE_ID);
134
+ if (!url) return;
135
+ const pricingVariants = pricingVariantsByPlanId && encodePricingVariants(pricingVariantsByPlanId);
136
+ return withQuery(url, queryOf([pricingVariants ? ["pricingVariants", pricingVariants] : ["planIds", planIds?.join(",")], ...checkoutQueryEntries(context, checkout)]));
137
+ }
138
+ //#endregion
139
+ //#region src/builder/success-url.ts
140
+ const BUILDER_THANK_YOU_PAGE_ID = "thank-you-page";
141
+ function withSuccessUrl(context, checkoutUrl, navigation) {
142
+ const thankYouPage = appPageUrl(context, BUILDER_THANK_YOU_PAGE_ID);
143
+ const target = returnUrl(context, navigation);
144
+ if (!thankYouPage || !target) return checkoutUrl;
145
+ const successUrl = new URL(thankYouPage);
146
+ const url = new URL(checkoutUrl);
147
+ successUrl.searchParams.set("returnUrl", target);
148
+ url.searchParams.set("successUrl", successUrl.href);
149
+ return url.href;
150
+ }
151
+ //#endregion
152
+ //#region src/adapters/navigate-to-page.ts
153
+ async function navigateToPage(navigateTo, href, pageName) {
154
+ if (!href) throw new Error(`Cannot navigate to ${pageName}, because it is not available on the site.`);
155
+ if (!await navigateTo(href)) throw new Error(`Navigation to ${pageName} failed.`);
156
+ }
157
+ async function getPageUrl(href, pageName) {
158
+ if (!href) throw new Error(`Cannot get ${pageName} URL, because it is not available on the site.`);
159
+ return href;
160
+ }
161
+ //#endregion
162
+ //#region src/adapters/builder.ts
163
+ function createBuilderSiteApi({ navigateTo, ...context }) {
164
+ return {
165
+ navigateToPricingPage: (options = {}) => navigateToPage(navigateTo, builderPricingPageUrl(context, options), "pricing page"),
166
+ getPricingPageUrl: (options = {}) => getPageUrl(builderPricingPageUrl(context, options), "pricing page"),
167
+ navigateToPlanPage: async (options) => {
168
+ const purchase = planPurchase(await loadPublicPlan(options.planId), options.pricingVariantId);
169
+ if (!purchase) throw new Error("Plan is not available for online purchase.");
170
+ if (purchase.requiresCustomization) return navigateToPage(navigateTo, builderPlanPageUrl(context, {
171
+ ...options,
172
+ pricingVariantId: purchase.pricingVariantId
173
+ }), "plan page");
174
+ return navigateToPage(navigateTo, withSuccessUrl(context, await createCheckoutUrl(options.planId, purchase.pricingVariantId), options.thankYouPage?.navigation), "checkout");
175
+ }
176
+ };
177
+ }
178
+ //#endregion
179
+ //#region src/legacy/pages.ts
180
+ const LEGACY_PRICING_PAGE_ID = "membership_plan_picker_tpa";
181
+ function findLegacyPricingPage(pages) {
182
+ return findAppPage(pages, LEGACY_PRICING_PAGE_ID);
183
+ }
184
+ //#endregion
185
+ //#region src/legacy/pricing-page-url.ts
186
+ function legacyPricingPageUrl(context, options) {
187
+ const url = appPageUrl(context, LEGACY_PRICING_PAGE_ID);
188
+ return url && withQuery(url, pricingPageQuery(options));
189
+ }
190
+ function pricingPageQuery({ planIds, pricingVariantsByPlanId, title, subtitle, biOptions, checkout }) {
191
+ const { content, navigation } = checkout?.thankYouPage ?? {};
192
+ const pricingVariants = pricingVariantsByPlanId && encodePricingVariants(pricingVariantsByPlanId);
193
+ return queryOf([
194
+ ["destination", navigation?.type === "url" ? navigation.url : void 0],
195
+ ["page", navigation?.type === "page" ? navigation.pageId : void 0],
196
+ ["section", navigation?.type === "section" ? encodeBase64Url(navigation.options) : void 0],
197
+ ["referral", biOptions?.referralInfo],
198
+ ["referralId", biOptions?.referralId],
199
+ ["maxStartDate", checkout?.maxStartDate],
200
+ ["minStartDate", checkout?.minStartDate],
201
+ ["thankYouTitle", content?.title],
202
+ ["thankYouMessage", content?.message],
203
+ ["thankYouCTA", content?.cta],
204
+ pricingVariants ? ["pricingVariants", pricingVariants] : ["planIds", planIds?.join(",")],
205
+ ["title", title],
206
+ ["subtitle", subtitle]
207
+ ]);
208
+ }
209
+ function encodeBase64Url(input) {
210
+ const bytes = encodeURIComponent(JSON.stringify(input)).replace(/%[0-9A-F]{2}/g, (percent) => String.fromCharCode(parseInt(percent.slice(1), 16)));
211
+ return btoa(bytes).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
212
+ }
213
+ //#endregion
214
+ //#region src/adapters/legacy-ooi.ts
215
+ function createLegacyOoiSiteApi({ navigateTo, callPublicApi, ...context }) {
216
+ return {
217
+ navigateToPricingPage: (options = {}) => navigateToPage(navigateTo, legacyPricingPageUrl(context, options), "pricing page"),
218
+ getPricingPageUrl: (options = {}) => getPageUrl(legacyPricingPageUrl(context, options), "pricing page"),
219
+ navigateToPlanPage: async (options) => {
220
+ await callPublicApi("navigateToPlanPage", [options]);
221
+ }
222
+ };
223
+ }
224
+ //#endregion
225
+ //#region src/adapters/not-installed.ts
226
+ const notInstalled = () => Promise.reject(/* @__PURE__ */ new Error("Pricing Plans is not installed on the site."));
227
+ function createNotInstalledSiteApi() {
228
+ return {
229
+ navigateToPricingPage: notInstalled,
230
+ getPricingPageUrl: notInstalled,
231
+ navigateToPlanPage: notInstalled
232
+ };
233
+ }
234
+ //#endregion
235
+ //#region src/create-site-api.ts
236
+ const BUILDER_PAGE_IDS = [
237
+ BUILDER_PRICING_PAGE_ID,
238
+ BUILDER_PLAN_PAGE_ID,
239
+ BUILDER_THANK_YOU_PAGE_ID
240
+ ];
241
+ function createSiteApi(context) {
242
+ if (findLegacyPricingPage(context.pages)) return createLegacyOoiSiteApi(context);
243
+ if (Object.values(context.pages).some((page) => page.appDefinitionId === "1522827f-c56c-a5c9-2ac9-00f9e6ae12d3") || BUILDER_PAGE_IDS.some((appPageId) => findAppPage(context.pages, appPageId))) return createBuilderSiteApi(context);
244
+ return createNotInstalledSiteApi();
245
+ }
246
+ //#endregion
247
+ //#region src/public-api-caller.ts
248
+ const PublicApiCallerDefinition = defineService("@wix/site-service-public-api-caller");
249
+ //#endregion
250
+ //#region src/router.ts
251
+ const LegacyRouterDefinition = defineService("@wix/viewer-service-router");
252
+ function getRouter(getService) {
253
+ try {
254
+ return getService(RouterDefinition);
255
+ } catch {
256
+ return getService(LegacyRouterDefinition);
257
+ }
258
+ }
259
+ //#endregion
260
+ //#region src/use-pricing-plans-site-api.ts
261
+ /**
262
+ * Navigation to Pricing Plans pages that works with both versions of the Pricing Plans app: the
263
+ * legacy app (OOI) and the Builder app. The hook detects which one the site runs and uses its
264
+ * pages, so the calls are the same for both.
265
+ *
266
+ * Calling the hook is safe on any site. When Pricing Plans isn't installed on the site, every method
267
+ * it returns rejects with the error `Pricing Plans is not installed on the site.` and doesn't
268
+ * navigate. The hook treats Pricing Plans as installed when the site has at least one Pricing Plans
269
+ * page.
270
+ *
271
+ * Use it inside a site component or context provider, and list these services in the extension's
272
+ * `serviceDependencies`: `@wix/site-service-pages`, `@wix/site-service-url`,
273
+ * `@wix/site-service-router`, `@wix/viewer-service-router` and
274
+ * `@wix/site-service-public-api-caller`.
275
+ *
276
+ * @example
277
+ * const { navigateToPlanPage } = usePricingPlansSiteApi();
278
+ *
279
+ * <button onClick={() => navigateToPlanPage({ planId })}>Buy plan</button>
280
+ */
281
+ function usePricingPlansSiteApi() {
282
+ const pages = usePages();
283
+ const url = useService(UrlDefinition);
284
+ const getService = useGetService();
285
+ return useMemo(() => createSiteApi({
286
+ pages,
287
+ siteUrl: url.siteUrl,
288
+ sectionUrl: (appDefinitionId, sectionId, discardRouterPageSuffix) => url.appSectionRelativeUrl(appDefinitionId, sectionId, discardRouterPageSuffix),
289
+ navigateTo: (href) => getRouter(getService).navigateTo({ href }),
290
+ callPublicApi: (methodPath, args) => getService(PublicApiCallerDefinition).callPublicApi(PRICING_PLANS_APP_ID, methodPath, args)
291
+ }), [
292
+ pages,
293
+ url,
294
+ getService
295
+ ]);
296
+ }
297
+ //#endregion
298
+ export { usePricingPlansSiteApi };
299
+
300
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/constants.ts","../src/builder/checkout.ts","../src/builder/plan-purchase.ts","../src/url.ts","../src/app-pages.ts","../src/builder/return-url.ts","../src/builder/checkout-query.ts","../src/builder/plan-page-url.ts","../src/builder/pricing-page-url.ts","../src/builder/success-url.ts","../src/adapters/navigate-to-page.ts","../src/adapters/builder.ts","../src/legacy/pages.ts","../src/legacy/pricing-page-url.ts","../src/adapters/legacy-ooi.ts","../src/adapters/not-installed.ts","../src/create-site-api.ts","../src/public-api-caller.ts","../src/router.ts","../src/use-pricing-plans-site-api.ts"],"sourcesContent":["export const PRICING_PLANS_APP_ID = '1522827f-c56c-a5c9-2ac9-00f9e6ae12d3';\n","import { cartV2 } from '@wix/ecom';\nimport { plansV3 } from '@wix/pricing-plans';\nimport { PRICING_PLANS_APP_ID } from '../constants';\n\nexport async function loadPublicPlan(planId: string): Promise<plansV3.Plan | undefined> {\n const { items } = await plansV3\n .queryPlans()\n .eq('_id', planId)\n .eq('visibility', 'PUBLIC')\n .limit(1)\n .find();\n\n return items[0];\n}\n\nexport async function createCheckoutUrl(planId: string, pricingVariantId: string): Promise<string> {\n const cart = await cartV2.createCart({\n cart: { source: { channelType: 'WEB' } },\n catalogItems: [\n {\n quantity: 1,\n catalogReference: {\n appId: PRICING_PLANS_APP_ID,\n catalogItemId: planId,\n options: { type: 'PLAN', planOptions: { pricingVariantId, membersOnly: false } },\n },\n },\n ],\n });\n\n if (!cart?._id) {\n throw new Error('Cart creation did not return an ID');\n }\n\n const { checkoutUrl } = await cartV2.getCheckoutUrl(cart._id);\n\n if (!checkoutUrl) {\n throw new Error('Checkout URL was not returned');\n }\n\n return checkoutUrl;\n}\n","import type { plansV3 } from '@wix/pricing-plans';\n\nexport type PlanPurchase = {\n pricingVariantId: string;\n requiresCustomization: boolean;\n};\n\nexport function planPurchase(\n plan: plansV3.Plan | undefined,\n pricingVariantId?: string,\n): PlanPurchase | undefined {\n if (!plan || plan.buyable !== true) return;\n\n const variants = (plan.pricingVariants ?? []).filter(\n (variant): variant is plansV3.PricingVariant & { _id: string } =>\n Boolean(variant._id) && variant.visible !== false,\n );\n // Like the legacy app, a hidden or unknown pricingVariantId falls back to the first visible variant.\n const variant = variants.find(({ _id }) => _id === pricingVariantId) ?? variants[0];\n\n if (!variant) return;\n\n const requiresStartDate = plan.startDateSettings\n ? plan.startDateSettings.type === 'DATE_RANGE'\n : variant.billingTerms?.startType === 'CUSTOM';\n\n return {\n pricingVariantId: variant._id,\n requiresCustomization: Boolean(plan.formId) || requiresStartDate,\n };\n}\n","export function siteHref(siteUrl: string, path: string): string {\n return `${siteUrl.replace(/\\/$/, '')}/${path.replace(/^\\//, '')}`;\n}\n\nexport function withQuery(url: string, query: URLSearchParams): string {\n const search = query.toString();\n\n return search ? `${url}?${search}` : url;\n}\n\nexport function queryOf(entries: Array<[string, string | undefined]>): URLSearchParams {\n return new URLSearchParams(\n entries.filter((entry): entry is [string, string] => Boolean(entry[1])),\n );\n}\n\nexport function encodePricingVariants(pricingVariantsByPlanId: Record<string, string[]>): string {\n return Object.entries(pricingVariantsByPlanId)\n .filter(([, pricingVariantIds]) => pricingVariantIds.length)\n .map(([planId, pricingVariantIds]) => [planId, ...pricingVariantIds].join(':'))\n .join(',');\n}\n","import { PRICING_PLANS_APP_ID } from './constants';\nimport type { Page, Pages, UrlContext } from './types';\nimport { siteHref } from './url';\n\nexport function findAppPage(pages: Pages, appPageId: string): Page | undefined {\n const candidates = Object.values(pages).filter(\n (page) => !page.popup && page.appPageId === appPageId,\n );\n const unowned = candidates.filter((page) => !page.appDefinitionId);\n\n return (\n candidates.find((page) => page.appDefinitionId === PRICING_PLANS_APP_ID) ??\n (unowned.length === 1 ? unowned[0] : undefined)\n );\n}\n\nexport function appPageUrl(context: UrlContext, appPageId: string): string | undefined {\n const path = findAppPage(context.pages, appPageId)\n ? context.sectionUrl(PRICING_PLANS_APP_ID, appPageId)\n : undefined;\n\n return path ? siteHref(context.siteUrl, path) : undefined;\n}\n","import type { NavigationPolicy, UrlContext } from '../types';\nimport { siteHref, withQuery } from '../url';\n\nexport function returnUrl(\n { pages, siteUrl, sectionUrl }: UrlContext,\n navigation: NavigationPolicy | undefined,\n): string | undefined {\n if (!navigation) return;\n\n switch (navigation.type) {\n case 'url':\n return onSiteUrl(siteUrl, navigation.url);\n case 'page': {\n const page = pages[navigation.pageId];\n\n return page && siteHref(siteUrl, page.path);\n }\n case 'section': {\n const { appDefinitionId, sectionId, state, queryParams, discardRouterPageSuffix } =\n navigation.options;\n const path = sectionUrl(appDefinitionId, sectionId, discardRouterPageSuffix);\n\n if (!path) return;\n\n const url = siteHref(siteUrl, state ? `${path.replace(/\\/$/, '')}/${state}` : path);\n\n return queryParams\n ? withQuery(url, new URLSearchParams({ appSectionParams: JSON.stringify(queryParams) }))\n : url;\n }\n }\n}\n\n// Matches the targets the Thank You page accepts as `returnUrl`; it sends any other to the homepage.\nfunction onSiteUrl(siteUrl: string, url: string): string | undefined {\n try {\n const site = new URL(siteUrl.endsWith('/') ? siteUrl : `${siteUrl}/`);\n const target = new URL(url.startsWith('/') ? siteHref(siteUrl, url) : url, site);\n const basePath = site.pathname.replace(/\\/$/, '');\n\n if (\n target.origin === site.origin &&\n !target.username &&\n !target.password &&\n (target.protocol === 'https:' || target.protocol === 'http:') &&\n (target.pathname === basePath || target.pathname.startsWith(`${basePath}/`))\n ) {\n return target.href;\n }\n } catch {\n return;\n }\n}\n","import type { CheckoutOptions, UrlContext } from '../types';\nimport { returnUrl } from './return-url';\n\nexport function checkoutQueryEntries(\n context: UrlContext,\n checkout: CheckoutOptions = {},\n): Array<[string, string | undefined]> {\n return [\n ['minStartDate', checkout.minStartDate],\n ['maxStartDate', checkout.maxStartDate],\n ['returnUrl', returnUrl(context, checkout.thankYouPage?.navigation)],\n ];\n}\n","import { appPageUrl } from '../app-pages';\nimport type { NavigateToPlanPageOptions, UrlContext } from '../types';\nimport { queryOf, withQuery } from '../url';\nimport { checkoutQueryEntries } from './checkout-query';\n\nexport const BUILDER_PLAN_PAGE_ID = 'plan-customization-page';\n\nexport function builderPlanPageUrl(\n context: UrlContext,\n { planId, pricingVariantId, ...checkout }: NavigateToPlanPageOptions,\n): string | undefined {\n const url = appPageUrl(context, BUILDER_PLAN_PAGE_ID);\n\n if (!url) return;\n\n return withQuery(\n url,\n queryOf([\n ['planId', planId],\n ['pricingVariantId', pricingVariantId],\n ...checkoutQueryEntries(context, checkout),\n ]),\n );\n}\n","import { appPageUrl } from '../app-pages';\nimport type { NavigateToPricingPageOptions, UrlContext } from '../types';\nimport { encodePricingVariants, queryOf, withQuery } from '../url';\nimport { checkoutQueryEntries } from './checkout-query';\n\nexport const BUILDER_PRICING_PAGE_ID = 'plans-page';\n\nexport function builderPricingPageUrl(\n context: UrlContext,\n { planIds, pricingVariantsByPlanId, checkout }: NavigateToPricingPageOptions,\n): string | undefined {\n const url = appPageUrl(context, BUILDER_PRICING_PAGE_ID);\n\n if (!url) return;\n\n const pricingVariants = pricingVariantsByPlanId && encodePricingVariants(pricingVariantsByPlanId);\n\n return withQuery(\n url,\n queryOf([\n pricingVariants ? ['pricingVariants', pricingVariants] : ['planIds', planIds?.join(',')],\n ...checkoutQueryEntries(context, checkout),\n ]),\n );\n}\n","import { appPageUrl } from '../app-pages';\nimport type { NavigationPolicy, UrlContext } from '../types';\nimport { returnUrl } from './return-url';\n\nexport const BUILDER_THANK_YOU_PAGE_ID = 'thank-you-page';\n\nexport function withSuccessUrl(\n context: UrlContext,\n checkoutUrl: string,\n navigation: NavigationPolicy | undefined,\n): string {\n const thankYouPage = appPageUrl(context, BUILDER_THANK_YOU_PAGE_ID);\n const target = returnUrl(context, navigation);\n\n if (!thankYouPage || !target) {\n return checkoutUrl;\n }\n\n const successUrl = new URL(thankYouPage);\n const url = new URL(checkoutUrl);\n\n successUrl.searchParams.set('returnUrl', target);\n url.searchParams.set('successUrl', successUrl.href);\n\n return url.href;\n}\n","import type { SiteApiContext } from '../types';\n\nexport async function navigateToPage(\n navigateTo: SiteApiContext['navigateTo'],\n href: string | undefined,\n pageName: string,\n): Promise<void> {\n if (!href) {\n throw new Error(`Cannot navigate to ${pageName}, because it is not available on the site.`);\n }\n\n if (!(await navigateTo(href))) {\n throw new Error(`Navigation to ${pageName} failed.`);\n }\n}\n\nexport async function getPageUrl(href: string | undefined, pageName: string): Promise<string> {\n if (!href) {\n throw new Error(`Cannot get ${pageName} URL, because it is not available on the site.`);\n }\n\n return href;\n}\n","import { createCheckoutUrl, loadPublicPlan } from '../builder/checkout';\nimport { planPurchase } from '../builder/plan-purchase';\nimport { builderPlanPageUrl } from '../builder/plan-page-url';\nimport { builderPricingPageUrl } from '../builder/pricing-page-url';\nimport { withSuccessUrl } from '../builder/success-url';\nimport type { SiteApiContext, PricingPlansSiteApi } from '../types';\nimport { getPageUrl, navigateToPage } from './navigate-to-page';\n\nexport function createBuilderSiteApi({\n navigateTo,\n ...context\n}: SiteApiContext): PricingPlansSiteApi {\n return {\n navigateToPricingPage: (options = {}) =>\n navigateToPage(navigateTo, builderPricingPageUrl(context, options), 'pricing page'),\n getPricingPageUrl: (options = {}) =>\n getPageUrl(builderPricingPageUrl(context, options), 'pricing page'),\n navigateToPlanPage: async (options) => {\n const purchase = planPurchase(await loadPublicPlan(options.planId), options.pricingVariantId);\n\n if (!purchase) {\n throw new Error('Plan is not available for online purchase.');\n }\n\n if (purchase.requiresCustomization) {\n return navigateToPage(\n navigateTo,\n builderPlanPageUrl(context, { ...options, pricingVariantId: purchase.pricingVariantId }),\n 'plan page',\n );\n }\n\n const checkoutUrl = await createCheckoutUrl(options.planId, purchase.pricingVariantId);\n\n return navigateToPage(\n navigateTo,\n withSuccessUrl(context, checkoutUrl, options.thankYouPage?.navigation),\n 'checkout',\n );\n },\n };\n}\n","import { findAppPage } from '../app-pages';\nimport type { Page, Pages } from '../types';\n\nexport const LEGACY_PRICING_PAGE_ID = 'membership_plan_picker_tpa';\n\nexport function findLegacyPricingPage(pages: Pages): Page | undefined {\n return findAppPage(pages, LEGACY_PRICING_PAGE_ID);\n}\n","import { appPageUrl } from '../app-pages';\nimport type { NavigateToPricingPageOptions, UrlContext } from '../types';\nimport { encodePricingVariants, queryOf, withQuery } from '../url';\nimport { LEGACY_PRICING_PAGE_ID } from './pages';\n\nexport function legacyPricingPageUrl(\n context: UrlContext,\n options: NavigateToPricingPageOptions,\n): string | undefined {\n const url = appPageUrl(context, LEGACY_PRICING_PAGE_ID);\n\n return url && withQuery(url, pricingPageQuery(options));\n}\n\nfunction pricingPageQuery({\n planIds,\n pricingVariantsByPlanId,\n title,\n subtitle,\n biOptions,\n checkout,\n}: NavigateToPricingPageOptions): URLSearchParams {\n const { content, navigation } = checkout?.thankYouPage ?? {};\n const pricingVariants = pricingVariantsByPlanId && encodePricingVariants(pricingVariantsByPlanId);\n\n return queryOf([\n ['destination', navigation?.type === 'url' ? navigation.url : undefined],\n ['page', navigation?.type === 'page' ? navigation.pageId : undefined],\n ['section', navigation?.type === 'section' ? encodeBase64Url(navigation.options) : undefined],\n ['referral', biOptions?.referralInfo],\n ['referralId', biOptions?.referralId],\n ['maxStartDate', checkout?.maxStartDate],\n ['minStartDate', checkout?.minStartDate],\n ['thankYouTitle', content?.title],\n ['thankYouMessage', content?.message],\n ['thankYouCTA', content?.cta],\n pricingVariants ? ['pricingVariants', pricingVariants] : ['planIds', planIds?.join(',')],\n ['title', title],\n ['subtitle', subtitle],\n ]);\n}\n\nfunction encodeBase64Url(input: unknown): string {\n const bytes = encodeURIComponent(JSON.stringify(input)).replace(/%[0-9A-F]{2}/g, (percent) =>\n String.fromCharCode(parseInt(percent.slice(1), 16)),\n );\n\n return btoa(bytes).replace(/=/g, '').replace(/\\+/g, '-').replace(/\\//g, '_');\n}\n","import { legacyPricingPageUrl } from '../legacy/pricing-page-url';\nimport type { SiteApiContext, PricingPlansSiteApi } from '../types';\nimport { getPageUrl, navigateToPage } from './navigate-to-page';\n\nexport function createLegacyOoiSiteApi({\n navigateTo,\n callPublicApi,\n ...context\n}: SiteApiContext): PricingPlansSiteApi {\n return {\n navigateToPricingPage: (options = {}) =>\n navigateToPage(navigateTo, legacyPricingPageUrl(context, options), 'pricing page'),\n getPricingPageUrl: (options = {}) =>\n getPageUrl(legacyPricingPageUrl(context, options), 'pricing page'),\n navigateToPlanPage: async (options) => {\n await callPublicApi('navigateToPlanPage', [options]);\n },\n };\n}\n","import type { PricingPlansSiteApi } from '../types';\n\nconst notInstalled = () => Promise.reject(new Error('Pricing Plans is not installed on the site.'));\n\nexport function createNotInstalledSiteApi(): PricingPlansSiteApi {\n return {\n navigateToPricingPage: notInstalled,\n getPricingPageUrl: notInstalled,\n navigateToPlanPage: notInstalled,\n };\n}\n","import { createBuilderSiteApi } from './adapters/builder';\nimport { createLegacyOoiSiteApi } from './adapters/legacy-ooi';\nimport { createNotInstalledSiteApi } from './adapters/not-installed';\nimport { findAppPage } from './app-pages';\nimport { BUILDER_PLAN_PAGE_ID } from './builder/plan-page-url';\nimport { BUILDER_PRICING_PAGE_ID } from './builder/pricing-page-url';\nimport { BUILDER_THANK_YOU_PAGE_ID } from './builder/success-url';\nimport { PRICING_PLANS_APP_ID } from './constants';\nimport { findLegacyPricingPage } from './legacy/pages';\nimport type { SiteApiContext, PricingPlansSiteApi } from './types';\n\nconst BUILDER_PAGE_IDS = [BUILDER_PRICING_PAGE_ID, BUILDER_PLAN_PAGE_ID, BUILDER_THANK_YOU_PAGE_ID];\n\nexport function createSiteApi(context: SiteApiContext): PricingPlansSiteApi {\n if (findLegacyPricingPage(context.pages)) {\n return createLegacyOoiSiteApi(context);\n }\n\n if (\n Object.values(context.pages).some((page) => page.appDefinitionId === PRICING_PLANS_APP_ID) ||\n BUILDER_PAGE_IDS.some((appPageId) => findAppPage(context.pages, appPageId))\n ) {\n return createBuilderSiteApi(context);\n }\n\n return createNotInstalledSiteApi();\n}\n","import { defineService } from '@wix/services-definitions';\n\ntype PublicApiCaller = {\n callPublicApi(\n appDefinitionId: string,\n methodPath: string | string[],\n args?: unknown[],\n ): Promise<unknown>;\n};\n\nexport const PublicApiCallerDefinition = defineService<PublicApiCaller>(\n '@wix/site-service-public-api-caller',\n);\n","import { defineService } from '@wix/services-definitions';\nimport type { GetService } from '@wix/services-definitions';\nimport { RouterDefinition } from '@wix/site-service-router/definition';\nimport type { IRouterService } from '@wix/site-service-router/definition';\n\nconst LegacyRouterDefinition = defineService<IRouterService>('@wix/viewer-service-router');\n\nexport function getRouter(getService: GetService): IRouterService {\n try {\n return getService(RouterDefinition);\n } catch {\n return getService(LegacyRouterDefinition);\n }\n}\n","import { usePages } from '@wix/react-component-utils';\nimport { useGetService, useService } from '@wix/services-manager-react';\nimport { UrlDefinition } from '@wix/site-service-url/definition';\nimport { useMemo } from 'react';\nimport { PRICING_PLANS_APP_ID } from './constants';\nimport { createSiteApi } from './create-site-api';\nimport { PublicApiCallerDefinition } from './public-api-caller';\nimport { getRouter } from './router';\nimport type { PricingPlansSiteApi } from './types';\n\n/**\n * Navigation to Pricing Plans pages that works with both versions of the Pricing Plans app: the\n * legacy app (OOI) and the Builder app. The hook detects which one the site runs and uses its\n * pages, so the calls are the same for both.\n *\n * Calling the hook is safe on any site. When Pricing Plans isn't installed on the site, every method\n * it returns rejects with the error `Pricing Plans is not installed on the site.` and doesn't\n * navigate. The hook treats Pricing Plans as installed when the site has at least one Pricing Plans\n * page.\n *\n * Use it inside a site component or context provider, and list these services in the extension's\n * `serviceDependencies`: `@wix/site-service-pages`, `@wix/site-service-url`,\n * `@wix/site-service-router`, `@wix/viewer-service-router` and\n * `@wix/site-service-public-api-caller`.\n *\n * @example\n * const { navigateToPlanPage } = usePricingPlansSiteApi();\n *\n * <button onClick={() => navigateToPlanPage({ planId })}>Buy plan</button>\n */\nexport function usePricingPlansSiteApi(): PricingPlansSiteApi {\n const pages = usePages();\n const url = useService(UrlDefinition);\n const getService = useGetService();\n\n return useMemo(\n () =>\n createSiteApi({\n pages,\n siteUrl: url.siteUrl,\n sectionUrl: (appDefinitionId, sectionId, discardRouterPageSuffix) =>\n url.appSectionRelativeUrl(appDefinitionId, sectionId, discardRouterPageSuffix),\n navigateTo: (href) => getRouter(getService).navigateTo({ href }),\n callPublicApi: (methodPath, args) =>\n getService(PublicApiCallerDefinition).callPublicApi(\n PRICING_PLANS_APP_ID,\n methodPath,\n args,\n ),\n }),\n [pages, url, getService],\n );\n}\n"],"mappings":";;;;;;;;;AAAA,MAAa,uBAAuB;;;ACIpC,eAAsB,eAAe,QAAmD;CACtF,MAAM,EAAE,UAAU,MAAM,QACrB,WAAW,CAAC,CACZ,GAAG,OAAO,MAAM,CAAC,CACjB,GAAG,cAAc,QAAQ,CAAC,CAC1B,MAAM,CAAC,CAAC,CACR,KAAK;CAER,OAAO,MAAM;AACf;AAEA,eAAsB,kBAAkB,QAAgB,kBAA2C;CACjG,MAAM,OAAO,MAAM,OAAO,WAAW;EACnC,MAAM,EAAE,QAAQ,EAAE,aAAa,MAAM,EAAE;EACvC,cAAc,CACZ;GACE,UAAU;GACV,kBAAkB;IAChB,OAAO;IACP,eAAe;IACf,SAAS;KAAE,MAAM;KAAQ,aAAa;MAAE;MAAkB,aAAa;KAAM;IAAE;GACjF;EACF,CACF;CACF,CAAC;CAED,IAAI,CAAC,MAAM,KACT,MAAM,IAAI,MAAM,oCAAoC;CAGtD,MAAM,EAAE,gBAAgB,MAAM,OAAO,eAAe,KAAK,GAAG;CAE5D,IAAI,CAAC,aACH,MAAM,IAAI,MAAM,+BAA+B;CAGjD,OAAO;AACT;;;AClCA,SAAgB,aACd,MACA,kBAC0B;CAC1B,IAAI,CAAC,QAAQ,KAAK,YAAY,MAAM;CAEpC,MAAM,YAAY,KAAK,mBAAmB,CAAC,EAAA,CAAG,QAC3C,YACC,QAAQ,QAAQ,GAAG,KAAK,QAAQ,YAAY,KAChD;CAEA,MAAM,UAAU,SAAS,MAAM,EAAE,UAAU,QAAQ,gBAAgB,KAAK,SAAS;CAEjF,IAAI,CAAC,SAAS;CAEd,MAAM,oBAAoB,KAAK,oBAC3B,KAAK,kBAAkB,SAAS,eAChC,QAAQ,cAAc,cAAc;CAExC,OAAO;EACL,kBAAkB,QAAQ;EAC1B,uBAAuB,QAAQ,KAAK,MAAM,KAAK;CACjD;AACF;;;AC9BA,SAAgB,SAAS,SAAiB,MAAsB;CAC9D,OAAO,GAAG,QAAQ,QAAQ,OAAO,EAAE,EAAE,GAAG,KAAK,QAAQ,OAAO,EAAE;AAChE;AAEA,SAAgB,UAAU,KAAa,OAAgC;CACrE,MAAM,SAAS,MAAM,SAAS;CAE9B,OAAO,SAAS,GAAG,IAAI,GAAG,WAAW;AACvC;AAEA,SAAgB,QAAQ,SAA+D;CACrF,OAAO,IAAI,gBACT,QAAQ,QAAQ,UAAqC,QAAQ,MAAM,EAAE,CAAC,CACxE;AACF;AAEA,SAAgB,sBAAsB,yBAA2D;CAC/F,OAAO,OAAO,QAAQ,uBAAuB,CAAC,CAC3C,QAAQ,GAAG,uBAAuB,kBAAkB,MAAM,CAAC,CAC3D,KAAK,CAAC,QAAQ,uBAAuB,CAAC,QAAQ,GAAG,iBAAiB,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAC9E,KAAK,GAAG;AACb;;;ACjBA,SAAgB,YAAY,OAAc,WAAqC;CAC7E,MAAM,aAAa,OAAO,OAAO,KAAK,CAAC,CAAC,QACrC,SAAS,CAAC,KAAK,SAAS,KAAK,cAAc,SAC9C;CACA,MAAM,UAAU,WAAW,QAAQ,SAAS,CAAC,KAAK,eAAe;CAEjE,OACE,WAAW,MAAM,SAAS,KAAK,oBAAA,sCAAwC,MACtE,QAAQ,WAAW,IAAI,QAAQ,KAAK,KAAA;AAEzC;AAEA,SAAgB,WAAW,SAAqB,WAAuC;CACrF,MAAM,OAAO,YAAY,QAAQ,OAAO,SAAS,IAC7C,QAAQ,WAAW,sBAAsB,SAAS,IAClD,KAAA;CAEJ,OAAO,OAAO,SAAS,QAAQ,SAAS,IAAI,IAAI,KAAA;AAClD;;;ACnBA,SAAgB,UACd,EAAE,OAAO,SAAS,cAClB,YACoB;CACpB,IAAI,CAAC,YAAY;CAEjB,QAAQ,WAAW,MAAnB;EACE,KAAK,OACH,OAAO,UAAU,SAAS,WAAW,GAAG;EAC1C,KAAK,QAAQ;GACX,MAAM,OAAO,MAAM,WAAW;GAE9B,OAAO,QAAQ,SAAS,SAAS,KAAK,IAAI;EAC5C;EACA,KAAK,WAAW;GACd,MAAM,EAAE,iBAAiB,WAAW,OAAO,aAAa,4BACtD,WAAW;GACb,MAAM,OAAO,WAAW,iBAAiB,WAAW,uBAAuB;GAE3E,IAAI,CAAC,MAAM;GAEX,MAAM,MAAM,SAAS,SAAS,QAAQ,GAAG,KAAK,QAAQ,OAAO,EAAE,EAAE,GAAG,UAAU,IAAI;GAElF,OAAO,cACH,UAAU,KAAK,IAAI,gBAAgB,EAAE,kBAAkB,KAAK,UAAU,WAAW,EAAE,CAAC,CAAC,IACrF;EACN;CACF;AACF;AAGA,SAAS,UAAU,SAAiB,KAAiC;CACnE,IAAI;EACF,MAAM,OAAO,IAAI,IAAI,QAAQ,SAAS,GAAG,IAAI,UAAU,GAAG,QAAQ,EAAE;EACpE,MAAM,SAAS,IAAI,IAAI,IAAI,WAAW,GAAG,IAAI,SAAS,SAAS,GAAG,IAAI,KAAK,IAAI;EAC/E,MAAM,WAAW,KAAK,SAAS,QAAQ,OAAO,EAAE;EAEhD,IACE,OAAO,WAAW,KAAK,UACvB,CAAC,OAAO,YACR,CAAC,OAAO,aACP,OAAO,aAAa,YAAY,OAAO,aAAa,aACpD,OAAO,aAAa,YAAY,OAAO,SAAS,WAAW,GAAG,SAAS,EAAE,IAE1E,OAAO,OAAO;CAElB,QAAQ;EACN;CACF;AACF;;;ACjDA,SAAgB,qBACd,SACA,WAA4B,CAAC,GACQ;CACrC,OAAO;EACL,CAAC,gBAAgB,SAAS,YAAY;EACtC,CAAC,gBAAgB,SAAS,YAAY;EACtC,CAAC,aAAa,UAAU,SAAS,SAAS,cAAc,UAAU,CAAC;CACrE;AACF;;;ACPA,MAAa,uBAAuB;AAEpC,SAAgB,mBACd,SACA,EAAE,QAAQ,kBAAkB,GAAG,YACX;CACpB,MAAM,MAAM,WAAW,SAAS,oBAAoB;CAEpD,IAAI,CAAC,KAAK;CAEV,OAAO,UACL,KACA,QAAQ;EACN,CAAC,UAAU,MAAM;EACjB,CAAC,oBAAoB,gBAAgB;EACrC,GAAG,qBAAqB,SAAS,QAAQ;CAC3C,CAAC,CACH;AACF;;;AClBA,MAAa,0BAA0B;AAEvC,SAAgB,sBACd,SACA,EAAE,SAAS,yBAAyB,YAChB;CACpB,MAAM,MAAM,WAAW,SAAS,uBAAuB;CAEvD,IAAI,CAAC,KAAK;CAEV,MAAM,kBAAkB,2BAA2B,sBAAsB,uBAAuB;CAEhG,OAAO,UACL,KACA,QAAQ,CACN,kBAAkB,CAAC,mBAAmB,eAAe,IAAI,CAAC,WAAW,SAAS,KAAK,GAAG,CAAC,GACvF,GAAG,qBAAqB,SAAS,QAAQ,CAC3C,CAAC,CACH;AACF;;;ACpBA,MAAa,4BAA4B;AAEzC,SAAgB,eACd,SACA,aACA,YACQ;CACR,MAAM,eAAe,WAAW,SAAS,yBAAyB;CAClE,MAAM,SAAS,UAAU,SAAS,UAAU;CAE5C,IAAI,CAAC,gBAAgB,CAAC,QACpB,OAAO;CAGT,MAAM,aAAa,IAAI,IAAI,YAAY;CACvC,MAAM,MAAM,IAAI,IAAI,WAAW;CAE/B,WAAW,aAAa,IAAI,aAAa,MAAM;CAC/C,IAAI,aAAa,IAAI,cAAc,WAAW,IAAI;CAElD,OAAO,IAAI;AACb;;;ACvBA,eAAsB,eACpB,YACA,MACA,UACe;CACf,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,sBAAsB,SAAS,2CAA2C;CAG5F,IAAI,CAAE,MAAM,WAAW,IAAI,GACzB,MAAM,IAAI,MAAM,iBAAiB,SAAS,SAAS;AAEvD;AAEA,eAAsB,WAAW,MAA0B,UAAmC;CAC5F,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,cAAc,SAAS,+CAA+C;CAGxF,OAAO;AACT;;;ACdA,SAAgB,qBAAqB,EACnC,YACA,GAAG,WACmC;CACtC,OAAO;EACL,wBAAwB,UAAU,CAAC,MACjC,eAAe,YAAY,sBAAsB,SAAS,OAAO,GAAG,cAAc;EACpF,oBAAoB,UAAU,CAAC,MAC7B,WAAW,sBAAsB,SAAS,OAAO,GAAG,cAAc;EACpE,oBAAoB,OAAO,YAAY;GACrC,MAAM,WAAW,aAAa,MAAM,eAAe,QAAQ,MAAM,GAAG,QAAQ,gBAAgB;GAE5F,IAAI,CAAC,UACH,MAAM,IAAI,MAAM,4CAA4C;GAG9D,IAAI,SAAS,uBACX,OAAO,eACL,YACA,mBAAmB,SAAS;IAAE,GAAG;IAAS,kBAAkB,SAAS;GAAiB,CAAC,GACvF,WACF;GAKF,OAAO,eACL,YACA,eAAe,SAAS,MAJA,kBAAkB,QAAQ,QAAQ,SAAS,gBAAgB,GAI9C,QAAQ,cAAc,UAAU,GACrE,UACF;EACF;CACF;AACF;;;ACtCA,MAAa,yBAAyB;AAEtC,SAAgB,sBAAsB,OAAgC;CACpE,OAAO,YAAY,OAAO,sBAAsB;AAClD;;;ACFA,SAAgB,qBACd,SACA,SACoB;CACpB,MAAM,MAAM,WAAW,SAAS,sBAAsB;CAEtD,OAAO,OAAO,UAAU,KAAK,iBAAiB,OAAO,CAAC;AACxD;AAEA,SAAS,iBAAiB,EACxB,SACA,yBACA,OACA,UACA,WACA,YACgD;CAChD,MAAM,EAAE,SAAS,eAAe,UAAU,gBAAgB,CAAC;CAC3D,MAAM,kBAAkB,2BAA2B,sBAAsB,uBAAuB;CAEhG,OAAO,QAAQ;EACb,CAAC,eAAe,YAAY,SAAS,QAAQ,WAAW,MAAM,KAAA,CAAS;EACvE,CAAC,QAAQ,YAAY,SAAS,SAAS,WAAW,SAAS,KAAA,CAAS;EACpE,CAAC,WAAW,YAAY,SAAS,YAAY,gBAAgB,WAAW,OAAO,IAAI,KAAA,CAAS;EAC5F,CAAC,YAAY,WAAW,YAAY;EACpC,CAAC,cAAc,WAAW,UAAU;EACpC,CAAC,gBAAgB,UAAU,YAAY;EACvC,CAAC,gBAAgB,UAAU,YAAY;EACvC,CAAC,iBAAiB,SAAS,KAAK;EAChC,CAAC,mBAAmB,SAAS,OAAO;EACpC,CAAC,eAAe,SAAS,GAAG;EAC5B,kBAAkB,CAAC,mBAAmB,eAAe,IAAI,CAAC,WAAW,SAAS,KAAK,GAAG,CAAC;EACvF,CAAC,SAAS,KAAK;EACf,CAAC,YAAY,QAAQ;CACvB,CAAC;AACH;AAEA,SAAS,gBAAgB,OAAwB;CAC/C,MAAM,QAAQ,mBAAmB,KAAK,UAAU,KAAK,CAAC,CAAC,CAAC,QAAQ,kBAAkB,YAChF,OAAO,aAAa,SAAS,QAAQ,MAAM,CAAC,GAAG,EAAE,CAAC,CACpD;CAEA,OAAO,KAAK,KAAK,CAAC,CAAC,QAAQ,MAAM,EAAE,CAAC,CAAC,QAAQ,OAAO,GAAG,CAAC,CAAC,QAAQ,OAAO,GAAG;AAC7E;;;AC5CA,SAAgB,uBAAuB,EACrC,YACA,eACA,GAAG,WACmC;CACtC,OAAO;EACL,wBAAwB,UAAU,CAAC,MACjC,eAAe,YAAY,qBAAqB,SAAS,OAAO,GAAG,cAAc;EACnF,oBAAoB,UAAU,CAAC,MAC7B,WAAW,qBAAqB,SAAS,OAAO,GAAG,cAAc;EACnE,oBAAoB,OAAO,YAAY;GACrC,MAAM,cAAc,sBAAsB,CAAC,OAAO,CAAC;EACrD;CACF;AACF;;;AChBA,MAAM,qBAAqB,QAAQ,uBAAO,IAAI,MAAM,6CAA6C,CAAC;AAElG,SAAgB,4BAAiD;CAC/D,OAAO;EACL,uBAAuB;EACvB,mBAAmB;EACnB,oBAAoB;CACtB;AACF;;;ACCA,MAAM,mBAAmB;CAAC;CAAyB;CAAsB;AAAyB;AAElG,SAAgB,cAAc,SAA8C;CAC1E,IAAI,sBAAsB,QAAQ,KAAK,GACrC,OAAO,uBAAuB,OAAO;CAGvC,IACE,OAAO,OAAO,QAAQ,KAAK,CAAC,CAAC,MAAM,SAAS,KAAK,oBAAA,sCAAwC,KACzF,iBAAiB,MAAM,cAAc,YAAY,QAAQ,OAAO,SAAS,CAAC,GAE1E,OAAO,qBAAqB,OAAO;CAGrC,OAAO,0BAA0B;AACnC;;;AChBA,MAAa,4BAA4B,cACvC,qCACF;;;ACPA,MAAM,yBAAyB,cAA8B,4BAA4B;AAEzF,SAAgB,UAAU,YAAwC;CAChE,IAAI;EACF,OAAO,WAAW,gBAAgB;CACpC,QAAQ;EACN,OAAO,WAAW,sBAAsB;CAC1C;AACF;;;;;;;;;;;;;;;;;;;;;;;ACiBA,SAAgB,yBAA8C;CAC5D,MAAM,QAAQ,SAAS;CACvB,MAAM,MAAM,WAAW,aAAa;CACpC,MAAM,aAAa,cAAc;CAEjC,OAAO,cAEH,cAAc;EACZ;EACA,SAAS,IAAI;EACb,aAAa,iBAAiB,WAAW,4BACvC,IAAI,sBAAsB,iBAAiB,WAAW,uBAAuB;EAC/E,aAAa,SAAS,UAAU,UAAU,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC;EAC/D,gBAAgB,YAAY,SAC1B,WAAW,yBAAyB,CAAC,CAAC,cACpC,sBACA,YACA,IACF;CACJ,CAAC,GACH;EAAC;EAAO;EAAK;CAAU,CACzB;AACF"}
package/package.json CHANGED
@@ -1,6 +1,66 @@
1
1
  {
2
2
  "name": "@wix/pricing-plans-site-api",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "1.0.0",
4
+ "files": [
5
+ "dist"
6
+ ],
7
+ "type": "module",
8
+ "sideEffects": false,
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
15
+ "publishConfig": {
16
+ "registry": "https://registry.npmjs.org/",
17
+ "access": "public"
18
+ },
19
+ "scripts": {
20
+ "lint": "oxlint",
21
+ "lint:fix": "oxlint --fix",
22
+ "fmt": "oxfmt",
23
+ "fmt:check": "oxfmt --check",
24
+ "build": "yarn typecheck && rolldown -c",
25
+ "typecheck": "tsc --noEmit",
26
+ "test": "vitest"
27
+ },
28
+ "dependencies": {
29
+ "@wix/ecom": "^1.0.2514",
30
+ "@wix/pricing-plans": "^1.0.403",
31
+ "@wix/services-definitions": "^1.0.5",
32
+ "@wix/site-service-router": "^1.0.1",
33
+ "@wix/site-service-url": "^1.0.2"
34
+ },
35
+ "devDependencies": {
36
+ "@types/react": "^18.3.31",
37
+ "@wix/fed-cli-oxlint": "^1.0.6",
38
+ "@wix/react-component-utils": "^1.13.0",
39
+ "@wix/services-manager-react": "^1.0.8",
40
+ "oxfmt": "^0.70.0",
41
+ "oxlint": "^1.85.0",
42
+ "react": "^18.3.1",
43
+ "rolldown": "^1.2.9",
44
+ "rolldown-plugin-dts": "^0.27.14",
45
+ "typescript": "^6.0.3",
46
+ "vitest": "^4.1.11"
47
+ },
48
+ "peerDependencies": {
49
+ "@wix/react-component-utils": "^1.13.0",
50
+ "@wix/services-manager-react": "^1.0.8",
51
+ "react": ">=18"
52
+ },
53
+ "wix": {
54
+ "artifact": {
55
+ "groupId": "com.wixpress.npm",
56
+ "artifactId": "pricing-plans-site-api"
57
+ },
58
+ "validations": {
59
+ "sourceOnly": [
60
+ "lint",
61
+ "fmt:check"
62
+ ]
63
+ }
64
+ },
65
+ "falconPackageHash": "9ad85277a4de2094e20da4400fed6f4e67a85c5dc4b70ea75c1f141a"
6
66
  }