@neta-art/cohub 4.7.1 → 4.8.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/dist/chunks/http.d.ts +2 -0
- package/dist/chunks/websocket.d.ts +5 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +20 -6
- package/docs/work-runtime-guide.md +4 -0
- package/package.json +1 -1
package/dist/chunks/http.d.ts
CHANGED
|
@@ -275,6 +275,7 @@ declare class WorkRuntimeApi {
|
|
|
275
275
|
}): Promise<boolean>;
|
|
276
276
|
purchase(input: {
|
|
277
277
|
productKey: string;
|
|
278
|
+
purchaseAttemptId?: string;
|
|
278
279
|
}): Promise<{
|
|
279
280
|
providerKey: string | null;
|
|
280
281
|
checkoutUrl: string | null;
|
|
@@ -1312,6 +1313,7 @@ declare class SpaceCommerceApi {
|
|
|
1312
1313
|
name: string;
|
|
1313
1314
|
description?: string;
|
|
1314
1315
|
amountUsd: number;
|
|
1316
|
+
cohubBalanceUsd?: number;
|
|
1315
1317
|
status?: "draft" | "active";
|
|
1316
1318
|
visibility?: "public" | "private";
|
|
1317
1319
|
}): Promise<{
|
|
@@ -2258,6 +2258,11 @@ type SpaceCommerceProduct = {
|
|
|
2258
2258
|
validity: string | null;
|
|
2259
2259
|
creditBenefits: SpaceCommerceProductCreditBenefit[];
|
|
2260
2260
|
};
|
|
2261
|
+
cohubBalance: {
|
|
2262
|
+
amountUsd: number;
|
|
2263
|
+
amountMinor: number;
|
|
2264
|
+
policyVersion: string;
|
|
2265
|
+
} | null;
|
|
2261
2266
|
isDefaultPlan: boolean;
|
|
2262
2267
|
};
|
|
2263
2268
|
type SpaceCommerceProductBenefitBinding = {
|
package/dist/index.d.ts
CHANGED
|
@@ -112,6 +112,7 @@ declare class CohubClient {
|
|
|
112
112
|
}) => Promise<WorkCommerceCreditConsumeResponse>;
|
|
113
113
|
purchase: (input: {
|
|
114
114
|
productKey: string;
|
|
115
|
+
purchaseAttemptId?: string;
|
|
115
116
|
}) => Promise<{
|
|
116
117
|
providerKey: string | null;
|
|
117
118
|
checkoutUrl: string | null;
|
|
@@ -157,6 +158,7 @@ type WorkAuthorizeRequest = {
|
|
|
157
158
|
type WorkPurchaseRequest = {
|
|
158
159
|
requestId: string;
|
|
159
160
|
productKey: string;
|
|
161
|
+
purchaseAttemptId: string;
|
|
160
162
|
};
|
|
161
163
|
/**
|
|
162
164
|
* Reactive dialog state managed by the core. The host (Svelte or React)
|
package/dist/index.js
CHANGED
|
@@ -94,7 +94,7 @@ const getParentOrigin = () => {
|
|
|
94
94
|
return null;
|
|
95
95
|
}
|
|
96
96
|
};
|
|
97
|
-
const generateRequestId = () => globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random()}`;
|
|
97
|
+
const generateRequestId = () => globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
98
98
|
/**
|
|
99
99
|
* Bridge-mode transport: posts messages to `window.parent` (the Cohub host
|
|
100
100
|
* embedding the work in an iframe) and listens for the matching reply.
|
|
@@ -400,9 +400,11 @@ var WorkRuntimeApi = class {
|
|
|
400
400
|
return Boolean(this.token);
|
|
401
401
|
}
|
|
402
402
|
async purchase(input) {
|
|
403
|
+
const purchaseAttemptId = input.purchaseAttemptId?.trim() || generateRequestId();
|
|
403
404
|
return (await this.transport.request({
|
|
404
405
|
type: "cohub.work.purchase",
|
|
405
|
-
productKey: input.productKey
|
|
406
|
+
productKey: input.productKey,
|
|
407
|
+
purchaseAttemptId
|
|
406
408
|
}, { timeoutMs: 12e4 }))?.checkout ?? null;
|
|
407
409
|
}
|
|
408
410
|
async checkoutState() {
|
|
@@ -830,7 +832,7 @@ function createWorkBridgeCore(config) {
|
|
|
830
832
|
sessionStorage.removeItem(pendingPurchaseStorageKey);
|
|
831
833
|
} catch {}
|
|
832
834
|
}
|
|
833
|
-
async function createPurchase(productKey) {
|
|
835
|
+
async function createPurchase(productKey, purchaseAttemptId) {
|
|
834
836
|
const userToken = await getAccessToken();
|
|
835
837
|
if (!userToken) {
|
|
836
838
|
await config.requestSignIn(typeof location !== "undefined" ? location.pathname + location.search + location.hash : "/");
|
|
@@ -842,7 +844,10 @@ function createWorkBridgeCore(config) {
|
|
|
842
844
|
Authorization: `Bearer ${userToken}`,
|
|
843
845
|
"Content-Type": "application/json"
|
|
844
846
|
},
|
|
845
|
-
body: JSON.stringify({
|
|
847
|
+
body: JSON.stringify({
|
|
848
|
+
productKey,
|
|
849
|
+
purchaseAttemptId
|
|
850
|
+
})
|
|
846
851
|
});
|
|
847
852
|
if (!response.ok) throw new Error((await response.json().catch(() => null))?.message ?? "Purchase failed.");
|
|
848
853
|
return (await response.json()).checkout ?? null;
|
|
@@ -897,9 +902,18 @@ function createWorkBridgeCore(config) {
|
|
|
897
902
|
});
|
|
898
903
|
return;
|
|
899
904
|
}
|
|
905
|
+
const purchaseAttemptId = (typeof data.purchaseAttemptId === "string" ? data.purchaseAttemptId.trim() : "") || data.requestId.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 128);
|
|
906
|
+
if (!/^[a-zA-Z0-9_-]{1,128}$/.test(purchaseAttemptId)) {
|
|
907
|
+
reply(data.requestId, {
|
|
908
|
+
type: "cohub.work.error",
|
|
909
|
+
message: "Purchase attempt id is invalid."
|
|
910
|
+
});
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
900
913
|
state.pendingPurchase = {
|
|
901
914
|
requestId: data.requestId,
|
|
902
|
-
productKey
|
|
915
|
+
productKey,
|
|
916
|
+
purchaseAttemptId
|
|
903
917
|
};
|
|
904
918
|
state.purchaseError = null;
|
|
905
919
|
state.purchaseOpen = true;
|
|
@@ -982,7 +996,7 @@ function createWorkBridgeCore(config) {
|
|
|
982
996
|
state.purchaseError = null;
|
|
983
997
|
notify();
|
|
984
998
|
try {
|
|
985
|
-
const checkout = await createPurchase(state.pendingPurchase.productKey);
|
|
999
|
+
const checkout = await createPurchase(state.pendingPurchase.productKey, state.pendingPurchase.purchaseAttemptId);
|
|
986
1000
|
reply(state.pendingPurchase.requestId, {
|
|
987
1001
|
type: "cohub.work.purchase.result",
|
|
988
1002
|
checkout
|
|
@@ -656,6 +656,10 @@ if (checkoutState.orderId) {
|
|
|
656
656
|
}
|
|
657
657
|
```
|
|
658
658
|
|
|
659
|
+
`purchase()` creates a purchase attempt ID automatically. If application code
|
|
660
|
+
retries the call after a timeout, pass the same `purchaseAttemptId` to ensure
|
|
661
|
+
the retry resolves to the original Billing order.
|
|
662
|
+
|
|
659
663
|
---
|
|
660
664
|
|
|
661
665
|
## 6. Complete working example
|