@colixsystems/widget-sdk 0.280.0 → 0.281.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 +5 -1
- package/dist/contract.cjs +10 -5
- package/dist/contract.js +10 -5
- package/dist/hooks.js +15 -12
- package/dist/index.d.ts +4 -2
- package/package.json +1 -1
- package/src/contract.js +10 -5
package/README.md
CHANGED
|
@@ -88,7 +88,11 @@ See the design reference for the full architecture: [`docs/architecture/widget-m
|
|
|
88
88
|
|
|
89
89
|
## Status
|
|
90
90
|
|
|
91
|
-
`v0.
|
|
91
|
+
`v0.281.0` — pre-publish. The package surface (types, function names, export paths) is the v1 contract; runtime behaviour for some hooks is stubbed (each hook documents what's wired and what isn't). It is **not yet published to npm**.
|
|
92
|
+
|
|
93
|
+
### What's new in 0.281.0 (contract 1.230.0)
|
|
94
|
+
|
|
95
|
+
**Paid page access in the store builds.** A workspace can sell a `useAccessPlans()` plan in its iOS and Android apps by naming a RevenueCat entitlement for it. In those builds `purchase(planId)` then opens the store's own in-app purchase sheet, and access arrives when RevenueCat confirms the purchase — call `refresh()` a moment later. Each plan now carries `purchase_available`; `purchaseAvailable` is `false` only when no plan can be bought here, so check the plan's own flag before showing its button. A plan or paid-app access bought on the web also grants its RevenueCat entitlement, so `usePurchases().entitlements` in the app includes it. `usePurchases()` itself stays native-only. The payments client's `purchaseAccessPlan()` may answer with `store_product_id` (`@colixsystems/payments-client` 0.4.0).
|
|
92
96
|
|
|
93
97
|
### What's new in 0.280.0 (contract 1.229.0)
|
|
94
98
|
|
package/dist/contract.cjs
CHANGED
|
@@ -2343,13 +2343,13 @@ const HOOKS = [
|
|
|
2343
2343
|
signature: "useAccessPlans()",
|
|
2344
2344
|
returnShape: {
|
|
2345
2345
|
plans:
|
|
2346
|
-
"Array<{ id, name, price_cents, currency, billing: \"one_time\" | \"monthly\", owned, renews, access_ends_at }> // owned: the user holds it; renews: a held monthly plan will charge again; access_ends_at: end of held access without a renewal (null for one-time)",
|
|
2346
|
+
"Array<{ id, name, price_cents, currency, billing: \"one_time\" | \"monthly\", owned, renews, access_ends_at, purchase_available }> // owned: the user holds it; renews: a held monthly plan will charge again; access_ends_at: end of held access without a renewal (null for one-time); purchase_available: this plan can be bought here — false in an iOS/Android build for a plan the workspace does not sell in-app",
|
|
2347
2347
|
loading: "boolean",
|
|
2348
2348
|
error: "PaymentError | null",
|
|
2349
2349
|
purchaseAvailable:
|
|
2350
|
-
"boolean // false
|
|
2350
|
+
"boolean // false when no plan can be bought here (an iOS/Android build where the workspace sells no plan in-app) — render a visible not-available state, never a dead button or a blank; check each plan's purchase_available too",
|
|
2351
2351
|
purchase:
|
|
2352
|
-
"(planId, { return_path? }?) => Promise<{ plan_id, status: \"ACTIVE\" | \"PENDING\" }> // pass ONLY the plan id; the server sets price and group; host opens hosted Checkout; access arrives with the payment confirmation",
|
|
2352
|
+
"(planId, { return_path? }?) => Promise<{ plan_id, status: \"ACTIVE\" | \"PENDING\" }> // pass ONLY the plan id; the server sets price and group; the host opens hosted Checkout on the web and the store's in-app purchase sheet in an iOS/Android build; access arrives with the payment confirmation, so refresh() a moment later",
|
|
2353
2353
|
cancel:
|
|
2354
2354
|
"(planId) => Promise<{ plan_id, renews: false, access_ends_at }> // stop a renewing monthly plan; access runs to access_ends_at — offer it beside every plan with renews: true",
|
|
2355
2355
|
refresh: "() => Promise<void> // re-read after returning from Checkout",
|
|
@@ -3171,7 +3171,9 @@ const HOOKS = [
|
|
|
3171
3171
|
"the buyer closed the sheet, so do not show it as a failure. A purchase needs a signed-in app user. NATIVE-ONLY: a " +
|
|
3172
3172
|
"browser has no App Store or Google Play billing, so the web Player (and the Studio canvas) report supported:false " +
|
|
3173
3173
|
"— ALWAYS render a visible 'available in the app' state there, never a blank or a dead button. The Expo export also " +
|
|
3174
|
-
"reports supported:false until the workspace connects RevenueCat in Payments and rebuilds the app."
|
|
3174
|
+
"reports supported:false until the workspace connects RevenueCat in Payments and rebuilds the app. On the web, sell " +
|
|
3175
|
+
"page access with useAccessPlans() instead: a web purchase of a plan (or of paid-app access) also grants its " +
|
|
3176
|
+
"RevenueCat entitlement, so `entitlements` in the app includes what the user bought on the web.",
|
|
3175
3177
|
returnShape: {
|
|
3176
3178
|
supported: "boolean // false on the web Player and in an app built without RevenueCat",
|
|
3177
3179
|
loading: "boolean",
|
|
@@ -6662,7 +6664,10 @@ const CONTRACT = deepFreeze({
|
|
|
6662
6664
|
// `kind` (physical | service | digital); three new PaymentError codes.
|
|
6663
6665
|
// 1.229.0: additive (sc-15167) — `useAccessPlans()`, and the payments slice
|
|
6664
6666
|
// gains `listAccessPlans` / `purchaseAccessPlan` / `cancelAccessPlan`.
|
|
6665
|
-
|
|
6667
|
+
// 1.230.0: additive (sc-15164) — each access plan carries
|
|
6668
|
+
// `purchase_available`; a store build buys a plan the workspace sells
|
|
6669
|
+
// in-app through the store, and web purchases grant RevenueCat entitlements.
|
|
6670
|
+
version: "1.230.0",
|
|
6666
6671
|
sharedTranslationKeys: SHARED_TRANSLATION_KEYS,
|
|
6667
6672
|
hooks: HOOKS,
|
|
6668
6673
|
primitives: PRIMITIVES,
|
package/dist/contract.js
CHANGED
|
@@ -2339,13 +2339,13 @@ const HOOKS = [
|
|
|
2339
2339
|
signature: "useAccessPlans()",
|
|
2340
2340
|
returnShape: {
|
|
2341
2341
|
plans:
|
|
2342
|
-
"Array<{ id, name, price_cents, currency, billing: \"one_time\" | \"monthly\", owned, renews, access_ends_at }> // owned: the user holds it; renews: a held monthly plan will charge again; access_ends_at: end of held access without a renewal (null for one-time)",
|
|
2342
|
+
"Array<{ id, name, price_cents, currency, billing: \"one_time\" | \"monthly\", owned, renews, access_ends_at, purchase_available }> // owned: the user holds it; renews: a held monthly plan will charge again; access_ends_at: end of held access without a renewal (null for one-time); purchase_available: this plan can be bought here — false in an iOS/Android build for a plan the workspace does not sell in-app",
|
|
2343
2343
|
loading: "boolean",
|
|
2344
2344
|
error: "PaymentError | null",
|
|
2345
2345
|
purchaseAvailable:
|
|
2346
|
-
"boolean // false
|
|
2346
|
+
"boolean // false when no plan can be bought here (an iOS/Android build where the workspace sells no plan in-app) — render a visible not-available state, never a dead button or a blank; check each plan's purchase_available too",
|
|
2347
2347
|
purchase:
|
|
2348
|
-
"(planId, { return_path? }?) => Promise<{ plan_id, status: \"ACTIVE\" | \"PENDING\" }> // pass ONLY the plan id; the server sets price and group; host opens hosted Checkout; access arrives with the payment confirmation",
|
|
2348
|
+
"(planId, { return_path? }?) => Promise<{ plan_id, status: \"ACTIVE\" | \"PENDING\" }> // pass ONLY the plan id; the server sets price and group; the host opens hosted Checkout on the web and the store's in-app purchase sheet in an iOS/Android build; access arrives with the payment confirmation, so refresh() a moment later",
|
|
2349
2349
|
cancel:
|
|
2350
2350
|
"(planId) => Promise<{ plan_id, renews: false, access_ends_at }> // stop a renewing monthly plan; access runs to access_ends_at — offer it beside every plan with renews: true",
|
|
2351
2351
|
refresh: "() => Promise<void> // re-read after returning from Checkout",
|
|
@@ -3167,7 +3167,9 @@ const HOOKS = [
|
|
|
3167
3167
|
"the buyer closed the sheet, so do not show it as a failure. A purchase needs a signed-in app user. NATIVE-ONLY: a " +
|
|
3168
3168
|
"browser has no App Store or Google Play billing, so the web Player (and the Studio canvas) report supported:false " +
|
|
3169
3169
|
"— ALWAYS render a visible 'available in the app' state there, never a blank or a dead button. The Expo export also " +
|
|
3170
|
-
"reports supported:false until the workspace connects RevenueCat in Payments and rebuilds the app."
|
|
3170
|
+
"reports supported:false until the workspace connects RevenueCat in Payments and rebuilds the app. On the web, sell " +
|
|
3171
|
+
"page access with useAccessPlans() instead: a web purchase of a plan (or of paid-app access) also grants its " +
|
|
3172
|
+
"RevenueCat entitlement, so `entitlements` in the app includes what the user bought on the web.",
|
|
3171
3173
|
returnShape: {
|
|
3172
3174
|
supported: "boolean // false on the web Player and in an app built without RevenueCat",
|
|
3173
3175
|
loading: "boolean",
|
|
@@ -6658,7 +6660,10 @@ const CONTRACT = deepFreeze({
|
|
|
6658
6660
|
// `kind` (physical | service | digital); three new PaymentError codes.
|
|
6659
6661
|
// 1.229.0: additive (sc-15167) — `useAccessPlans()`, and the payments slice
|
|
6660
6662
|
// gains `listAccessPlans` / `purchaseAccessPlan` / `cancelAccessPlan`.
|
|
6661
|
-
|
|
6663
|
+
// 1.230.0: additive (sc-15164) — each access plan carries
|
|
6664
|
+
// `purchase_available`; a store build buys a plan the workspace sells
|
|
6665
|
+
// in-app through the store, and web purchases grant RevenueCat entitlements.
|
|
6666
|
+
version: "1.230.0",
|
|
6662
6667
|
sharedTranslationKeys: SHARED_TRANSLATION_KEYS,
|
|
6663
6668
|
hooks: HOOKS,
|
|
6664
6669
|
primitives: PRIMITIVES,
|
package/dist/hooks.js
CHANGED
|
@@ -7075,21 +7075,24 @@ export function usePayments() {
|
|
|
7075
7075
|
* `{ plans, loading, error, purchaseAvailable, purchase, cancel, refresh }`:
|
|
7076
7076
|
*
|
|
7077
7077
|
* plans → [{ id, name, price_cents, currency, billing, owned, renews,
|
|
7078
|
-
* access_ends_at }] — `billing` is "one_time" or
|
|
7079
|
-
* true once the user holds the plan; `renews` while
|
|
7080
|
-
* will charge again; `access_ends_at` is when held
|
|
7081
|
-
* renewal (null for one-time access)
|
|
7078
|
+
* access_ends_at, purchase_available }] — `billing` is "one_time" or
|
|
7079
|
+
* "monthly"; `owned` is true once the user holds the plan; `renews` while
|
|
7080
|
+
* a held monthly plan will charge again; `access_ends_at` is when held
|
|
7081
|
+
* access ends without a renewal (null for one-time access);
|
|
7082
|
+
* `purchase_available` is whether this plan can be bought here.
|
|
7082
7083
|
* Render the price with `useWorkspaceCurrency().formatMoney(price_cents)`.
|
|
7083
|
-
* purchaseAvailable → false where
|
|
7084
|
-
* digital good, and an iOS / Android build
|
|
7085
|
-
*
|
|
7086
|
-
*
|
|
7084
|
+
* purchaseAvailable → false where no plan can be bought here: page access is
|
|
7085
|
+
* a digital good, and an iOS / Android build sells only the plans the
|
|
7086
|
+
* workspace sells in-app (through store billing). Render a visible "not
|
|
7087
|
+
* available in this app" state for a plan whose `purchase_available` is
|
|
7088
|
+
* false — never a dead button and never a blank render.
|
|
7087
7089
|
* purchase(planId, { return_path? }?) → Promise<{ plan_id, status }>. Pass
|
|
7088
7090
|
* ONLY the plan id: the server sets the price and the group, so a widget can
|
|
7089
|
-
* never name an amount. The HOST
|
|
7090
|
-
* in-app
|
|
7091
|
-
* once (the mock provider) and
|
|
7092
|
-
*
|
|
7091
|
+
* never name an amount. The HOST takes the payment: hosted Checkout on the
|
|
7092
|
+
* web, the store's in-app purchase sheet in an iOS / Android build. `status`
|
|
7093
|
+
* is "ACTIVE" when access was granted at once (the mock provider) and
|
|
7094
|
+
* "PENDING" while payment is confirmed; access arrives with the
|
|
7095
|
+
* confirmation, never from the client.
|
|
7093
7096
|
* cancel(planId) → Promise<{ plan_id, renews: false, access_ends_at }> —
|
|
7094
7097
|
* stop a held monthly plan renewing (`renews` true). Access continues
|
|
7095
7098
|
* until `access_ends_at`; offer it beside every renewing plan.
|
package/dist/index.d.ts
CHANGED
|
@@ -1527,6 +1527,8 @@ export interface AccessPlan {
|
|
|
1527
1527
|
renews: boolean;
|
|
1528
1528
|
/** ISO time held access ends without a renewal; null for one-time access. */
|
|
1529
1529
|
access_ends_at: string | null;
|
|
1530
|
+
/** Whether this plan can be bought here (false in a store build that does not sell it in-app). */
|
|
1531
|
+
purchase_available: boolean;
|
|
1530
1532
|
}
|
|
1531
1533
|
|
|
1532
1534
|
export interface AccessPlanPurchase {
|
|
@@ -1540,8 +1542,8 @@ export interface AccessPlansApi {
|
|
|
1540
1542
|
loading: boolean;
|
|
1541
1543
|
error: PaymentError | null;
|
|
1542
1544
|
/**
|
|
1543
|
-
* False where
|
|
1544
|
-
*
|
|
1545
|
+
* False where no plan can be bought here (an iOS / Android build sells only
|
|
1546
|
+
* the plans the workspace sells in-app): render a visible not-available state.
|
|
1545
1547
|
*/
|
|
1546
1548
|
purchaseAvailable: boolean;
|
|
1547
1549
|
/** Pass only the plan id; the server sets price and group. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@colixsystems/widget-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.281.0",
|
|
4
4
|
"description": "Common widget interface for AppStudio. Implements WidgetManifest, WidgetContext, property schema, and helper hooks.",
|
|
5
5
|
"homepage": "https://github.com/Colix-AB/AppStudio",
|
|
6
6
|
"type": "module",
|
package/src/contract.js
CHANGED
|
@@ -2339,13 +2339,13 @@ const HOOKS = [
|
|
|
2339
2339
|
signature: "useAccessPlans()",
|
|
2340
2340
|
returnShape: {
|
|
2341
2341
|
plans:
|
|
2342
|
-
"Array<{ id, name, price_cents, currency, billing: \"one_time\" | \"monthly\", owned, renews, access_ends_at }> // owned: the user holds it; renews: a held monthly plan will charge again; access_ends_at: end of held access without a renewal (null for one-time)",
|
|
2342
|
+
"Array<{ id, name, price_cents, currency, billing: \"one_time\" | \"monthly\", owned, renews, access_ends_at, purchase_available }> // owned: the user holds it; renews: a held monthly plan will charge again; access_ends_at: end of held access without a renewal (null for one-time); purchase_available: this plan can be bought here — false in an iOS/Android build for a plan the workspace does not sell in-app",
|
|
2343
2343
|
loading: "boolean",
|
|
2344
2344
|
error: "PaymentError | null",
|
|
2345
2345
|
purchaseAvailable:
|
|
2346
|
-
"boolean // false
|
|
2346
|
+
"boolean // false when no plan can be bought here (an iOS/Android build where the workspace sells no plan in-app) — render a visible not-available state, never a dead button or a blank; check each plan's purchase_available too",
|
|
2347
2347
|
purchase:
|
|
2348
|
-
"(planId, { return_path? }?) => Promise<{ plan_id, status: \"ACTIVE\" | \"PENDING\" }> // pass ONLY the plan id; the server sets price and group; host opens hosted Checkout; access arrives with the payment confirmation",
|
|
2348
|
+
"(planId, { return_path? }?) => Promise<{ plan_id, status: \"ACTIVE\" | \"PENDING\" }> // pass ONLY the plan id; the server sets price and group; the host opens hosted Checkout on the web and the store's in-app purchase sheet in an iOS/Android build; access arrives with the payment confirmation, so refresh() a moment later",
|
|
2349
2349
|
cancel:
|
|
2350
2350
|
"(planId) => Promise<{ plan_id, renews: false, access_ends_at }> // stop a renewing monthly plan; access runs to access_ends_at — offer it beside every plan with renews: true",
|
|
2351
2351
|
refresh: "() => Promise<void> // re-read after returning from Checkout",
|
|
@@ -3167,7 +3167,9 @@ const HOOKS = [
|
|
|
3167
3167
|
"the buyer closed the sheet, so do not show it as a failure. A purchase needs a signed-in app user. NATIVE-ONLY: a " +
|
|
3168
3168
|
"browser has no App Store or Google Play billing, so the web Player (and the Studio canvas) report supported:false " +
|
|
3169
3169
|
"— ALWAYS render a visible 'available in the app' state there, never a blank or a dead button. The Expo export also " +
|
|
3170
|
-
"reports supported:false until the workspace connects RevenueCat in Payments and rebuilds the app."
|
|
3170
|
+
"reports supported:false until the workspace connects RevenueCat in Payments and rebuilds the app. On the web, sell " +
|
|
3171
|
+
"page access with useAccessPlans() instead: a web purchase of a plan (or of paid-app access) also grants its " +
|
|
3172
|
+
"RevenueCat entitlement, so `entitlements` in the app includes what the user bought on the web.",
|
|
3171
3173
|
returnShape: {
|
|
3172
3174
|
supported: "boolean // false on the web Player and in an app built without RevenueCat",
|
|
3173
3175
|
loading: "boolean",
|
|
@@ -6658,7 +6660,10 @@ const CONTRACT = deepFreeze({
|
|
|
6658
6660
|
// `kind` (physical | service | digital); three new PaymentError codes.
|
|
6659
6661
|
// 1.229.0: additive (sc-15167) — `useAccessPlans()`, and the payments slice
|
|
6660
6662
|
// gains `listAccessPlans` / `purchaseAccessPlan` / `cancelAccessPlan`.
|
|
6661
|
-
|
|
6663
|
+
// 1.230.0: additive (sc-15164) — each access plan carries
|
|
6664
|
+
// `purchase_available`; a store build buys a plan the workspace sells
|
|
6665
|
+
// in-app through the store, and web purchases grant RevenueCat entitlements.
|
|
6666
|
+
version: "1.230.0",
|
|
6662
6667
|
sharedTranslationKeys: SHARED_TRANSLATION_KEYS,
|
|
6663
6668
|
hooks: HOOKS,
|
|
6664
6669
|
primitives: PRIMITIVES,
|