palbase 0.8.0 → 0.9.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/ai/index.js +2 -2
- package/dist/backend/engine.js +2 -2
- package/dist/backend/env.js +1 -1
- package/dist/backend/index.js +3 -3
- package/dist/backend/stack.js +1 -1
- package/dist/backend/test.js +2 -2
- package/dist/chunks/{RO5Y5YU4.js → 23G5YVSL.js} +1 -1
- package/dist/chunks/{JSJVV43D.js → 3X7CRIHE.js} +1 -1
- package/dist/chunks/5UXVSEM2.js +2 -0
- package/dist/chunks/6YCANJ7U.js +2 -0
- package/dist/chunks/{BO5KR2EQ.js → 7HMBZG2R.js} +2 -2
- package/dist/chunks/{RBA6V3UO.js → 7OZCS3BA.js} +2 -2
- package/dist/chunks/FFWT3RBE.js +13 -0
- package/dist/chunks/{TUGRIOFX.js → GGKL7UV2.js} +2 -2
- package/dist/chunks/HGQXQMYU.js +95 -0
- package/dist/chunks/{Z5JVQNAZ.js → I45DYZZL.js} +2 -2
- package/dist/chunks/{WEI32SAJ.js → KSU226RI.js} +2 -2
- package/dist/chunks/MEIN5GAG.js +22 -0
- package/dist/chunks/OEZLXSQN.js +6 -0
- package/dist/chunks/{BRBCWPR3.js → OGREZP5F.js} +1 -1
- package/dist/chunks/{PGPQGKH2.js → ONP77MHF.js} +2 -2
- package/dist/chunks/{KDWDPSL2.js → QR4Z3ORW.js} +1 -1
- package/dist/chunks/{K6RRNI23.js → R5NCHIW3.js} +2 -2
- package/dist/chunks/{PDOHT46N.js → RV35QG7V.js} +2 -2
- package/dist/chunks/{P4Z5E6ZI.js → YOTK5642.js} +2 -2
- package/dist/chunks/{5VTGMNPL.js → Z7VRCVKE.js} +6 -6
- package/dist/cli.js +129 -127
- package/dist/refuse/ai.js +1 -1
- package/dist/refuse/backend.js +1 -1
- package/dist/refuse/server.js +1 -1
- package/dist/server/index.js +2 -2
- package/dist/server/testing.js +2 -2
- package/dist/web/index.js +2 -2
- package/dist/web/message.js +2 -0
- package/dist/web/palbe.js +2 -2
- package/dist/web/paywall.js +2 -2
- package/dist/web/push-sw.js +2 -0
- package/dist/web/ssr.js +2 -2
- package/dist/web/vite.js +2 -2
- package/package.json +9 -2
- package/types/backend/src/services.d.ts +2 -2
- package/types/internal/src/modules/ai.d.ts +1 -1
- package/types/internal/src/modules/analytics.d.ts +618 -1
- package/types/internal/src/modules/auth.d.ts +409 -90
- package/types/internal/src/modules/events.d.ts +7 -3
- package/types/internal/src/modules/flags.d.ts +380 -14
- package/types/internal/src/modules/notify.d.ts +2270 -99
- package/types/internal/src/modules/purchases.d.ts +773 -2
- package/types/server/src/webhooks.d.ts +1 -1
- package/types/web/src/analytics.d.ts +56 -5
- package/types/web/src/client.d.ts +26 -4
- package/types/web/src/consent.d.ts +218 -0
- package/types/web/src/flags.d.ts +75 -0
- package/types/web/src/inapp.d.ts +129 -0
- package/types/web/src/inbox.d.ts +59 -0
- package/types/web/src/index.d.ts +9 -3
- package/types/web/src/installation.d.ts +16 -0
- package/types/web/src/message/index.d.ts +5 -0
- package/types/web/src/message/present.d.ts +20 -0
- package/types/web/src/notify.d.ts +67 -0
- package/types/web/src/paywall/index.d.ts +4 -4
- package/types/web/src/paywall/placement.d.ts +11 -12
- package/types/web/src/paywall/prices.d.ts +7 -2
- package/types/web/src/purchases.d.ts +80 -5
- package/types/web/src/{paywall → screen}/assets.d.ts +6 -6
- package/types/web/src/screen/render.d.ts +186 -0
- package/types/web/src/{paywall → screen}/resolve.d.ts +56 -8
- package/dist/chunks/DB3SIBKB.js +0 -2
- package/dist/chunks/EGNEXFTZ.js +0 -2
- package/dist/chunks/FZ3MQOVA.js +0 -6
- package/dist/chunks/WINBISC2.js +0 -92
- package/types/web/src/paywall/render.d.ts +0 -93
- /package/types/web/src/{paywall → screen}/icons.d.ts +0 -0
package/types/web/src/index.d.ts
CHANGED
|
@@ -2,13 +2,19 @@ export { createClient, type ClientOptions, type PalbaseClient } from './client.j
|
|
|
2
2
|
export type { Auth, CredentialsLike, SignInResult, User } from './auth.js';
|
|
3
3
|
export { localStore, memoryStore, SessionChangedError, type AuthEvent, type RefreshMode, type Session, type SessionEndReason, type SessionStore } from './session.js';
|
|
4
4
|
export { Channel, RealtimeSocket, type ChannelOptions, type PushReply } from './socket.js';
|
|
5
|
-
export { Analytics, type AnalyticsOptions } from './analytics.js';
|
|
5
|
+
export { Analytics, type AnalyticsOptions, type People } from './analytics.js';
|
|
6
|
+
export { Consent, type ConsentKeyInfo, type ConsentListener, type ConsentOptions, type ConsentRegion, type ConsentState } from './consent.js';
|
|
7
|
+
export { Installation } from './installation.js';
|
|
6
8
|
export type { AgentEvent, ChatAttachment, ChatEvent, ChatGoal, ChatItem, ChatMessageView, ChatPart, ChatPartsPage, ChatPartsQuery, ChatResponse, ChatState, ChatStreamPart, ChatThinking, ChatToolCall, ChatVoice, GatewayChat, GoalEvent, HistoryEvent, HistoryItem, Publication, ThinkingEvent, ToolEvent, TranscriptEvent, TurnEnd, TurnEvent, VoiceEvent, } from './chat.js';
|
|
7
9
|
export { connectVoice, type StartedVoice, type VoiceConnection, type VoiceOptions } from './voice.js';
|
|
8
|
-
export { Purchases, type CustomerInfo, type CustomerInfoListener, type MergeGrant, type Offerings } from './purchases.js';
|
|
10
|
+
export { Purchases, redemptionToken, type CheckoutSource, type CustomerInfo, type CustomerInfoListener, type GrantInfo, type MergeGrant, type OfferView, type Offerings, type Redeemed, type RedemptionLink, } from './purchases.js';
|
|
11
|
+
export { Notify, WebPush, type PushPermission, type PushSubscribeOptions } from './notify.js';
|
|
12
|
+
export { Flags, type FlagSource, type FlagsListener } from './flags.js';
|
|
13
|
+
export { Inbox, type InboxItem, type InboxListOptions, type InboxPage, type InboxView, type InboxViewOptions } from './inbox.js';
|
|
14
|
+
export { InApp, SESSION_START, type InAppOptions } from './inapp.js';
|
|
9
15
|
export type { Paywall, PaywallRenderOptions } from './paywall/placement.js';
|
|
10
16
|
export type { PaywallAttribute } from './paywall/attributes.js';
|
|
11
|
-
export type { PaywallPackage, PaywallView } from './
|
|
17
|
+
export type { PaywallPackage, PaywallView } from './screen/render.js';
|
|
12
18
|
export { PalbaseError } from '../../internal/src/transport.js';
|
|
13
19
|
export { BackendError, isBackendError, type BackendErrorKind, type FieldError } from './backend-error.js';
|
|
14
20
|
export type { BackendBase, CallOptions, UploadOptions, UploadProgress } from './backends.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** The header the install's secret is sent in, on the calls that act for the device itself. */
|
|
2
|
+
export declare const INSTALLATION_SECRET_HEADER = "X-Palbase-Installation-Secret";
|
|
3
|
+
/** The header the install's label is sent in. */
|
|
4
|
+
export declare const INSTALLATION_HEADER = "X-Palbase-Installation";
|
|
5
|
+
/** The install's secret: for the calls that act for the device itself, and only those. */
|
|
6
|
+
export declare function secretOf(installation: Installation): string;
|
|
7
|
+
/** Whether this page made the install: a new one, which the project holds nothing of. */
|
|
8
|
+
export declare function madeHere(installation: Installation): boolean;
|
|
9
|
+
export declare class Installation {
|
|
10
|
+
/** The installation id: this browser's, for this project, until its storage is cleared. */
|
|
11
|
+
readonly id: string;
|
|
12
|
+
constructor(origin: string);
|
|
13
|
+
}
|
|
14
|
+
/** The label a secret makes: the first 16 bytes of its SHA-256, base64url. */
|
|
15
|
+
export declare function labelOf(secret: string): string;
|
|
16
|
+
export declare function sha256(data: Uint8Array): Uint8Array;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { MESSAGE_COMPONENTS, MESSAGE_SCHEMA, countdownValues, messageResolution as resolveMessageWithPaths, resolveMessage, type Appearance, type MessageDefinition, type MessageResolveOptions, type Platform, type ResolvedMessage, type ResolvedNode, type ResolvedPresentation, type ResolvedStyle, type Resolution, } from '../screen/resolve.js';
|
|
2
|
+
export { renderMessage, type MessageActionTaken, type MessageHandlers, type MessageInput, type MessageState, type MessageView } from '../screen/render.js';
|
|
3
|
+
export { presentMessage, type MessageCloseReason, type PresentedMessage, type PresentHandlers, type PresentOptions } from './present.js';
|
|
4
|
+
export { assetId, fontFamily, htmlDocument, prepareAssets, unzip, type PreparedAsset, type ScreenAssetRef } from '../screen/assets.js';
|
|
5
|
+
export { ICONS as MESSAGE_ICONS } from '../screen/icons.js';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type MessageHandlers, type MessageInput, type MessageView } from '../screen/render.js';
|
|
2
|
+
/** How a message closed: a close button, an action that closes it, a tap outside, a swipe, its time, Escape, or the app. */
|
|
3
|
+
export type MessageCloseReason = 'button' | 'action' | 'outside' | 'swipe' | 'timeout' | 'escape' | 'app';
|
|
4
|
+
export interface PresentHandlers extends Omit<MessageHandlers, 'onClose'> {
|
|
5
|
+
/** Told once, when it has closed, with how. */
|
|
6
|
+
onClose?(reason: MessageCloseReason): void;
|
|
7
|
+
}
|
|
8
|
+
export interface PresentOptions {
|
|
9
|
+
/** The element it is shown in: the page's body unless given. */
|
|
10
|
+
root?: HTMLElement;
|
|
11
|
+
}
|
|
12
|
+
export interface PresentedMessage {
|
|
13
|
+
readonly view: MessageView;
|
|
14
|
+
/** How it closed, once it has. */
|
|
15
|
+
readonly closed: Promise<MessageCloseReason>;
|
|
16
|
+
/** Closes it: the app's reason (a navigation, another message). */
|
|
17
|
+
close(): void;
|
|
18
|
+
}
|
|
19
|
+
/** Shows a message over the page. A card is not shown so (it throws): an inbox draws it in its list. */
|
|
20
|
+
export declare function presentMessage(input: MessageInput, handlers?: PresentHandlers, options?: PresentOptions): PresentedMessage;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { Transport } from '../../internal/src/transport.js';
|
|
2
|
+
import { type Installation } from './installation.js';
|
|
3
|
+
import type { SessionManager } from './session.js';
|
|
4
|
+
import type { Consent } from './consent.js';
|
|
5
|
+
import type { Purchases } from './purchases.js';
|
|
6
|
+
import { Inbox } from './inbox.js';
|
|
7
|
+
import { InApp } from './inapp.js';
|
|
8
|
+
/** Where the browser is with pushes: allowed, refused, not asked yet, or a browser without them. */
|
|
9
|
+
export type PushPermission = 'granted' | 'denied' | 'default' | 'unsupported';
|
|
10
|
+
export interface PushSubscribeOptions {
|
|
11
|
+
/** The service worker that shows the pushes: the app's copy of palbase/web/push-sw.js at its origin; `/palbase-sw.js` unless given. */
|
|
12
|
+
serviceWorker?: string;
|
|
13
|
+
/** The worker's scope: its folder unless given. */
|
|
14
|
+
scope?: string;
|
|
15
|
+
}
|
|
16
|
+
type Globals = {
|
|
17
|
+
navigator?: {
|
|
18
|
+
serviceWorker?: ServiceWorkerContainer;
|
|
19
|
+
language?: string;
|
|
20
|
+
};
|
|
21
|
+
Notification?: {
|
|
22
|
+
permission: NotificationPermission;
|
|
23
|
+
requestPermission(): Promise<NotificationPermission>;
|
|
24
|
+
};
|
|
25
|
+
PushManager?: unknown;
|
|
26
|
+
};
|
|
27
|
+
/** This browser's pushes. */
|
|
28
|
+
export declare class WebPush {
|
|
29
|
+
private api;
|
|
30
|
+
private session;
|
|
31
|
+
private installation;
|
|
32
|
+
private baseUrl;
|
|
33
|
+
private publishableKey;
|
|
34
|
+
private g;
|
|
35
|
+
private registered;
|
|
36
|
+
/** The registration again for a change of who is signed in, while it runs. */
|
|
37
|
+
changing: Promise<unknown>;
|
|
38
|
+
constructor(transport: Transport, session: SessionManager, installation: Installation, baseUrl: string, publishableKey: string, g?: Globals);
|
|
39
|
+
/** Whether this browser takes pushes at all (a service worker, the Push API, notifications). */
|
|
40
|
+
supported(): boolean;
|
|
41
|
+
/** Whether the person allowed this site's notifications. */
|
|
42
|
+
permission(): PushPermission;
|
|
43
|
+
/** The service worker's address: the app's copy of push-sw.js, told the project's address and publishable key it reports with. */
|
|
44
|
+
workerUrl(path?: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* Asks the person for notifications (call it from a tap), subscribes this browser and registers it: true when it
|
|
47
|
+
* takes pushes now, false when the person refused or the browser has none.
|
|
48
|
+
*/
|
|
49
|
+
subscribe(opts?: PushSubscribeOptions): Promise<boolean>;
|
|
50
|
+
/** Stops this browser's pushes: its subscription ends, and the project forgets the device as it next pushes it. */
|
|
51
|
+
unsubscribe(): Promise<void>;
|
|
52
|
+
/** Registers the browser's subscription again (as the app starts, or as people sign in and out): nothing when it has none. */
|
|
53
|
+
refresh(): Promise<void>;
|
|
54
|
+
private current;
|
|
55
|
+
private register;
|
|
56
|
+
}
|
|
57
|
+
/** pb.notify: the project's notifications, as this app takes them. */
|
|
58
|
+
export declare class Notify {
|
|
59
|
+
/** This browser's pushes (Web Push). */
|
|
60
|
+
readonly push: WebPush;
|
|
61
|
+
/** The signed-in person's inbox, the same on each of their devices. */
|
|
62
|
+
readonly inbox: Inbox;
|
|
63
|
+
/** The project's in-app campaigns, shown in this page once started. */
|
|
64
|
+
readonly inApp: InApp;
|
|
65
|
+
constructor(transport: Transport, session: SessionManager, installation: Installation, consent: Consent, purchases: Purchases, baseUrl: string, publishableKey: string);
|
|
66
|
+
}
|
|
67
|
+
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { PAYWALL_COMPONENTS, PAYWALL_SCHEMA, countdownValues, packagesOf, resolution as resolvePaywallWithPaths, resolve as resolvePaywall, type Appearance, type PackageValues, type PaywallDefinition, type Platform, type ResolvedNode, type ResolvedPaywall, type ResolvedStyle, type Resolution, type ResolveOptions, } from '
|
|
2
|
-
export { renderPaywall, type PaywallHandlers, type PaywallInput, type PaywallPackage, type PaywallState, type PaywallView } from '
|
|
3
|
-
export { assetId, fontFamily, htmlDocument, prepareAssets, unzip, type
|
|
1
|
+
export { PAYWALL_COMPONENTS, PAYWALL_SCHEMA, countdownValues, packagesOf, resolution as resolvePaywallWithPaths, resolve as resolvePaywall, type Appearance, type PackageValues, type PaywallDefinition, type Platform, type ResolvedNode, type ResolvedPaywall, type ResolvedStyle, type Resolution, type ResolveOptions, } from '../screen/resolve.js';
|
|
2
|
+
export { renderPaywall, type PaywallHandlers, type PaywallInput, type PaywallPackage, type PaywallState, type PaywallView } from '../screen/render.js';
|
|
3
|
+
export { assetId, fontFamily, htmlDocument, prepareAssets, unzip, type PreparedAsset, type ScreenAssetRef as PaywallAssetRef } from '../screen/assets.js';
|
|
4
4
|
export { attributesHeader, type PaywallAttribute } from './attributes.js';
|
|
5
5
|
export { formatPeriod, formatPrice, packageValues, parseDuration, type PricedPackage } from './prices.js';
|
|
6
|
-
export { ICONS as PAYWALL_ICONS } from '
|
|
6
|
+
export { ICONS as PAYWALL_ICONS } from '../screen/icons.js';
|
|
7
7
|
export { Paywall, defaultPaywall, type PaywallRenderOptions } from './placement.js';
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { purchases as purchasesModule } from '../../../internal/src/modules/index.js';
|
|
2
|
-
import { type PreparedAsset } from '
|
|
2
|
+
import { type PreparedAsset } from '../screen/assets.js';
|
|
3
3
|
import { type PaywallAttribute } from './attributes.js';
|
|
4
4
|
import { type PricedPackage } from './prices.js';
|
|
5
|
-
import { type PaywallHandlers, type PaywallPackage, type PaywallView } from '
|
|
6
|
-
import { type Appearance, type PackageValues, type PaywallDefinition } from '
|
|
5
|
+
import { type PaywallHandlers, type PaywallPackage, type PaywallView } from '../screen/render.js';
|
|
6
|
+
import { type Appearance, type PackageValues, type PaywallDefinition } from '../screen/resolve.js';
|
|
7
7
|
type Offerings = purchasesModule.Offerings;
|
|
8
|
+
type OfferView = purchasesModule.OfferView;
|
|
8
9
|
type Api = ReturnType<typeof purchasesModule.client>;
|
|
9
10
|
export interface PaywallRenderOptions {
|
|
10
11
|
/** Stripe sends the customer back here after buying (one of the project's registered apps). */
|
|
@@ -36,6 +37,7 @@ interface PaywallDeps {
|
|
|
36
37
|
plan: string;
|
|
37
38
|
successUrl: string;
|
|
38
39
|
cancelUrl: string;
|
|
40
|
+
offer?: string;
|
|
39
41
|
}): Promise<string>;
|
|
40
42
|
expose(paywall: Paywall): Promise<void>;
|
|
41
43
|
}
|
|
@@ -49,6 +51,8 @@ export declare class Paywall {
|
|
|
49
51
|
readonly assets: Record<string, PreparedAsset>;
|
|
50
52
|
/** What the paywall sells on the web, priced as the catalog prices it. */
|
|
51
53
|
readonly offerings: Offerings;
|
|
54
|
+
/** The offers its packages are sold with that the signed-in customer may take now: bought with, and priced by. */
|
|
55
|
+
readonly offers: OfferView[];
|
|
52
56
|
/** The paywall and the version shown, the experiment's variant or the placement's rule that chose it; absent for the SDK's own. */
|
|
53
57
|
readonly shown: {
|
|
54
58
|
paywallId: string;
|
|
@@ -58,7 +62,7 @@ export declare class Paywall {
|
|
|
58
62
|
} | undefined;
|
|
59
63
|
private deps;
|
|
60
64
|
private exposed;
|
|
61
|
-
constructor(placement: string, source: Paywall['source'], definition: PaywallDefinition, offerings: Offerings, shown: Paywall['shown'], deps: PaywallDeps, assets?: Record<string, PreparedAsset
|
|
65
|
+
constructor(placement: string, source: Paywall['source'], definition: PaywallDefinition, offerings: Offerings, shown: Paywall['shown'], deps: PaywallDeps, assets?: Record<string, PreparedAsset>, offers?: OfferView[]);
|
|
62
66
|
/** The store's values of each package the paywall sells, in a language: what its texts' variables read. */
|
|
63
67
|
packages(locale: string): Record<string, PackageValues>;
|
|
64
68
|
/**
|
|
@@ -69,8 +73,8 @@ export declare class Paywall {
|
|
|
69
73
|
*/
|
|
70
74
|
render(container: HTMLElement, opts: PaywallRenderOptions): PaywallView;
|
|
71
75
|
}
|
|
72
|
-
/** The packages the web sells of those named, priced as its catalog prices them. */
|
|
73
|
-
export declare function webPackages(offerings: Offerings, keys: readonly string[], locale: string): PricedPackage[];
|
|
76
|
+
/** The packages the web sells of those named, priced as its catalog prices them — and as the offer each is sold with prices it, by key. */
|
|
77
|
+
export declare function webPackages(offerings: Offerings, keys: readonly string[], locale: string, offers?: ReadonlyMap<string, OfferView>): PricedPackage[];
|
|
74
78
|
/**
|
|
75
79
|
* The SDK's own paywall, where nothing is published: every plan the web
|
|
76
80
|
* sells (the first six) as a card — its product, period and price —, the
|
|
@@ -81,12 +85,7 @@ export declare function defaultPaywall(offerings: Offerings): PaywallDefinition
|
|
|
81
85
|
/** This browser's installation id: who a paywall is shown to before anyone signs in — the same experiment variant every time. */
|
|
82
86
|
export declare function installationId(ref: string): string;
|
|
83
87
|
/** The placement's paywall (see Purchases.paywall). */
|
|
84
|
-
export declare function loadPaywall(api: Api, ref: string, placement: string, checkout:
|
|
85
|
-
product: string;
|
|
86
|
-
plan: string;
|
|
87
|
-
successUrl: string;
|
|
88
|
-
cancelUrl: string;
|
|
89
|
-
}) => Promise<string>, ask?: {
|
|
88
|
+
export declare function loadPaywall(api: Api, ref: string, placement: string, checkout: PaywallDeps['checkout'], ask?: {
|
|
90
89
|
signal?: AbortSignal;
|
|
91
90
|
fetch?: (input: string, init?: RequestInit) => Promise<Response>;
|
|
92
91
|
/** What the app says of the person, for the placement's targeting rules. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PackageValues } from '
|
|
1
|
+
import type { PackageValues } from '../screen/resolve.js';
|
|
2
2
|
/** A package as a channel sells it: its product's name there, its price and, for a subscription, its period and trial. */
|
|
3
3
|
export interface PricedPackage {
|
|
4
4
|
/** `<product>.<plan>` */
|
|
@@ -16,6 +16,10 @@ export interface PricedPackage {
|
|
|
16
16
|
mode: string;
|
|
17
17
|
duration: string;
|
|
18
18
|
};
|
|
19
|
+
/** The catalog's offer it is sold with while the customer may take it: the percent off its price — all of it for a free trial —, its `{{offer_price}}`. */
|
|
20
|
+
offer?: {
|
|
21
|
+
percentOff: number;
|
|
22
|
+
};
|
|
19
23
|
}
|
|
20
24
|
interface Duration {
|
|
21
25
|
count: number;
|
|
@@ -34,7 +38,8 @@ export declare function formatPeriod(d: Duration, locale: string): string;
|
|
|
34
38
|
* subscription saves a month against the dearest a month of the packages
|
|
35
39
|
* given in its currency (none for the dearest, nor below 1%); a package
|
|
36
40
|
* that is not a subscription has no `{{period}}`, `{{price_per_month}}` or
|
|
37
|
-
* `{{savings}}`,
|
|
41
|
+
* `{{savings}}`, one without a free trial no `{{trial}}`, and one sold
|
|
42
|
+
* with no offer no `{{offer_price}}` (the resolver makes it the price).
|
|
38
43
|
*/
|
|
39
44
|
export declare function packageValues(packages: readonly PricedPackage[], locale: string): Record<string, PackageValues>;
|
|
40
45
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { purchases as purchasesModule } from '../../internal/src/modules/index.js';
|
|
2
|
-
import type
|
|
2
|
+
import { type Fetch, type Transport } from '../../internal/src/transport.js';
|
|
3
3
|
import type { SessionManager } from './session.js';
|
|
4
4
|
import type { RealtimeSocket } from './socket.js';
|
|
5
5
|
import type { PaywallAttribute } from './paywall/attributes.js';
|
|
@@ -8,6 +8,12 @@ type P = typeof purchasesModule;
|
|
|
8
8
|
export type CustomerInfo = purchasesModule.CustomerInfo;
|
|
9
9
|
export type Offerings = purchasesModule.Offerings;
|
|
10
10
|
export type MergeGrant = purchasesModule.MergeGrant;
|
|
11
|
+
export type OfferView = purchasesModule.OfferView;
|
|
12
|
+
export type GrantInfo = purchasesModule.GrantInfo;
|
|
13
|
+
export type Redeemed = purchasesModule.Redeemed;
|
|
14
|
+
export type RedemptionLink = purchasesModule.RedemptionLink;
|
|
15
|
+
/** Where a checkout is opened: an app linking out to buy on the web says its platform and its store's storefront (ISO 3166-1 alpha-3: `USA`). */
|
|
16
|
+
export type CheckoutSource = purchasesModule.CheckoutSource;
|
|
11
17
|
/** Told what the customer has: on the first read, then each time it changes; null while no one is signed in. */
|
|
12
18
|
export type CustomerInfoListener = (info: CustomerInfo | null) => void;
|
|
13
19
|
export declare class Purchases {
|
|
@@ -59,17 +65,82 @@ export declare class Purchases {
|
|
|
59
65
|
signal?: AbortSignal;
|
|
60
66
|
}): Promise<Paywall | null>;
|
|
61
67
|
/**
|
|
62
|
-
* Opens Stripe Checkout
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
68
|
+
* Opens Stripe Checkout to buy a product's plan sold on the web: the URL to
|
|
69
|
+
* send the buyer to. Stripe sends them back to successUrl or cancelUrl —
|
|
70
|
+
* one of the project's registered apps. Signed in — a guest too — the
|
|
71
|
+
* purchase is the customer's once Stripe reports it: onCustomerInfo hears
|
|
72
|
+
* it. With no one signed in the buyer is no one yet: Checkout asks their
|
|
73
|
+
* email, no free trial is given, and what they buy waits for the app user
|
|
74
|
+
* who redeems it — its link is on the success page (redemptionLink: put
|
|
75
|
+
* `{CHECKOUT_SESSION_ID}` in successUrl, Stripe writes the session's id
|
|
76
|
+
* there) and in their email. The key the success page asks it with is
|
|
77
|
+
* kept in this tab's sessionStorage, which the redirect to Stripe and back
|
|
78
|
+
* keeps. `source` says where the checkout was opened, when an app links
|
|
79
|
+
* out.
|
|
80
|
+
*
|
|
81
|
+
* `offer` buys it with one of the signed-in customer's offers on that plan
|
|
82
|
+
* (offers()): its discount — the coupon code that opened it, when one did,
|
|
83
|
+
* shown on Stripe's page — or its free trial. One that is not theirs to take
|
|
84
|
+
* there, or asked with no one signed in, is refused (403 offer_not_open).
|
|
66
85
|
*/
|
|
67
86
|
checkout(opts: {
|
|
68
87
|
product: string;
|
|
69
88
|
plan: string;
|
|
70
89
|
successUrl: string;
|
|
71
90
|
cancelUrl: string;
|
|
91
|
+
source?: CheckoutSource;
|
|
92
|
+
offer?: string;
|
|
72
93
|
}): Promise<string>;
|
|
94
|
+
/**
|
|
95
|
+
* On a checkout's success page, for a buyer with no account: the one-time
|
|
96
|
+
* link — good for an hour — that hands what they bought to the app user
|
|
97
|
+
* who opens it on their phone (show it, and its QR code on a computer).
|
|
98
|
+
* sessionId is Stripe's (`{CHECKOUT_SESSION_ID}` in successUrl); the key
|
|
99
|
+
* is the one checkout() kept in this tab, or `key` when the app kept it
|
|
100
|
+
* itself — without it the page has none to show (`redemption_key_missing`:
|
|
101
|
+
* the buyer's email has it). Stripe may not have told of the payment yet:
|
|
102
|
+
* it is asked again for up to waitSeconds (20). Each call makes a new
|
|
103
|
+
* link — ten at most, within an hour of the payment.
|
|
104
|
+
*/
|
|
105
|
+
redemptionLink(sessionId: string, opts?: {
|
|
106
|
+
key?: string;
|
|
107
|
+
waitSeconds?: number;
|
|
108
|
+
signal?: AbortSignal;
|
|
109
|
+
}): Promise<RedemptionLink>;
|
|
110
|
+
/**
|
|
111
|
+
* Redeems a web purchase's link for the signed-in user — a guest too, whose
|
|
112
|
+
* purchases go with it to the account it signs in to: what it bought is
|
|
113
|
+
* theirs; what they have now. Takes the link the app was opened with
|
|
114
|
+
* (`<scheme>://palbase/redeem?token=…`, or its page's
|
|
115
|
+
* `https://…/purchases/redeem?token=…`) or its token. A link works once (409
|
|
116
|
+
* `already_redeemed`); one past its hour is refused (410
|
|
117
|
+
* `redemption_expired`) and sends a new one to the buyer's email — the
|
|
118
|
+
* error's `body.resent` says so.
|
|
119
|
+
*/
|
|
120
|
+
redeem(link: string): Promise<CustomerInfo>;
|
|
121
|
+
/**
|
|
122
|
+
* The catalog's offers the signed-in customer may take now — each once:
|
|
123
|
+
* live, for everyone or an audience they are in (having allowed
|
|
124
|
+
* personalization), or opened to them by a coupon they redeemed. A
|
|
125
|
+
* discount or a trial is bought with (checkout's `offer`, on one of its
|
|
126
|
+
* web plans); a grant is claimed (claimOffer).
|
|
127
|
+
*/
|
|
128
|
+
offers(): Promise<OfferView[]>;
|
|
129
|
+
/** Tells the project the app showed the customer an offer: the first time is counted in the offer's figures. */
|
|
130
|
+
offerShown(key: string): Promise<void>;
|
|
131
|
+
/**
|
|
132
|
+
* Takes a grant offer: its entitlement, for its duration from now — onCustomerInfo hears it. Refused for a guest
|
|
133
|
+
* (403 account_required) and for an offer that is not the customer's to take now.
|
|
134
|
+
*/
|
|
135
|
+
claimOffer(key: string): Promise<GrantInfo>;
|
|
136
|
+
/**
|
|
137
|
+
* Redeems a code the customer typed, in any case — once a customer: what it opened, a grant given at once, a
|
|
138
|
+
* discount or a trial theirs to buy from now (offers() lists it with the coupon). A refusal is a PalbaseError
|
|
139
|
+
* with the module's code: coupon_not_found (404); coupon_redeemed, code_used (409); coupon_ended,
|
|
140
|
+
* coupon_exhausted, offer_ended (410); sign_in_required (403: a guest); redeem_at_app_store (422: an App Store
|
|
141
|
+
* offer code, redeemed in the App Store); too_many_attempts (429: too many codes tried — after retryAfter).
|
|
142
|
+
*/
|
|
143
|
+
redeemCoupon(code: string): Promise<Redeemed>;
|
|
73
144
|
/** Stripe's customer portal for what the customer bought on the web: the URL to send them to, and back to returnUrl. */
|
|
74
145
|
portal(returnUrl: string): Promise<string>;
|
|
75
146
|
/**
|
|
@@ -85,6 +156,8 @@ export declare class Purchases {
|
|
|
85
156
|
* grant, it is the same merge.
|
|
86
157
|
*/
|
|
87
158
|
merge(grant: MergeGrant | string): Promise<CustomerInfo>;
|
|
159
|
+
/** Where this tab keeps a checkout's redemption key. */
|
|
160
|
+
private keyName;
|
|
88
161
|
/**
|
|
89
162
|
* Listens to what the signed-in customer has: told it once read, then each
|
|
90
163
|
* time it changes — a purchase in any store, a renewal or its end, a
|
|
@@ -104,4 +177,6 @@ export declare class Purchases {
|
|
|
104
177
|
private offer;
|
|
105
178
|
private tell;
|
|
106
179
|
}
|
|
180
|
+
/** A redemption link's token: of `<scheme>://palbase/redeem?token=…`, of its page `…/purchases/redeem?token=…`, or the token itself. */
|
|
181
|
+
export declare function redemptionToken(link: string): string | undefined;
|
|
107
182
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/** An asset as the answer lists it (PaywallAssetRef). */
|
|
2
|
-
export interface
|
|
1
|
+
/** An asset as the answer lists it (purchases' PaywallAssetRef, notify's InAppAssetRef). */
|
|
2
|
+
export interface ScreenAssetRef {
|
|
3
3
|
id: string;
|
|
4
4
|
kind: 'image' | 'video' | 'font' | 'html';
|
|
5
5
|
url: string;
|
|
@@ -8,7 +8,7 @@ export interface PaywallAssetRef {
|
|
|
8
8
|
}
|
|
9
9
|
/** An asset ready to draw. */
|
|
10
10
|
export interface PreparedAsset {
|
|
11
|
-
kind:
|
|
11
|
+
kind: ScreenAssetRef['kind'];
|
|
12
12
|
/** Where its checked bytes are: an object URL (or, unchecked, the https address Studio's preview draws from). */
|
|
13
13
|
url: string;
|
|
14
14
|
/** A font's family, registered with the page's fonts. */
|
|
@@ -28,17 +28,17 @@ export interface PrepareOptions {
|
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
30
|
* Downloads and checks every asset; those that pass are ready to draw, by
|
|
31
|
-
* id. Done when the
|
|
31
|
+
* id. Done when the screen is fetched, before it is shown: what is shown
|
|
32
32
|
* then draws from memory.
|
|
33
33
|
*/
|
|
34
|
-
export declare function prepareAssets(refs: readonly
|
|
34
|
+
export declare function prepareAssets(refs: readonly ScreenAssetRef[], opts?: PrepareOptions): Promise<Record<string, PreparedAsset>>;
|
|
35
35
|
/**
|
|
36
36
|
* What an asset's bytes are, among the formats its kind takes — the type its
|
|
37
37
|
* object URL is given: an image is PNG, JPEG or WebP; a video MP4, QuickTime
|
|
38
38
|
* or WebM; a font WOFF2, WOFF, TrueType or OpenType; an HTML block a zip.
|
|
39
39
|
* Undefined for anything else: the asset is not drawn.
|
|
40
40
|
*/
|
|
41
|
-
export declare function formatOf(kind:
|
|
41
|
+
export declare function formatOf(kind: ScreenAssetRef['kind'], b: Uint8Array): string | undefined;
|
|
42
42
|
/** The files of a zip, by path: stored and deflated entries (what the server takes). */
|
|
43
43
|
export declare function unzip(bytes: Uint8Array): Promise<Map<string, Uint8Array>>;
|
|
44
44
|
/** The content security of an HTML block: it loads what is inside its document, and nothing from anywhere else. */
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { type PreparedAsset } from './assets.js';
|
|
2
|
+
import { type Appearance, type MessageDefinition, type PackageValues, type PaywallDefinition, type Platform } from './resolve.js';
|
|
3
|
+
/** A package of the catalog: what the purchase button buys. */
|
|
4
|
+
export interface PaywallPackage {
|
|
5
|
+
product: string;
|
|
6
|
+
plan: string;
|
|
7
|
+
/** The catalog's offer it is bought with: the one it is sold with, while the customer may take it. */
|
|
8
|
+
offer?: string;
|
|
9
|
+
}
|
|
10
|
+
/** What a paywall is drawn from. */
|
|
11
|
+
export interface PaywallInput {
|
|
12
|
+
definition: PaywallDefinition;
|
|
13
|
+
/** The reader's language (`tr-TR`). */
|
|
14
|
+
locale: string;
|
|
15
|
+
appearance: Appearance;
|
|
16
|
+
/** Where it is drawn: the web, unless a preview draws another platform's. */
|
|
17
|
+
platform?: Platform;
|
|
18
|
+
/** The store's values of each package, by `<product>.<plan>`; a package without any is drawn, not sold. */
|
|
19
|
+
packages: Record<string, PackageValues>;
|
|
20
|
+
/** The packages whose introductory offer the customer can still take. */
|
|
21
|
+
eligible?: readonly string[];
|
|
22
|
+
/** The catalog's offers the customer may take now: a package sold with one is bought with it, its `{{offer_price}}` the offer's (its values'). */
|
|
23
|
+
offers?: readonly string[];
|
|
24
|
+
/** The app's own addresses of `terms` and `privacy` (https); a button or link to one is not drawn without it. */
|
|
25
|
+
links?: {
|
|
26
|
+
terms?: string;
|
|
27
|
+
privacy?: string;
|
|
28
|
+
};
|
|
29
|
+
/** The definition's assets ready to draw, by id (prepareAssets): one missing is drawn without. */
|
|
30
|
+
assets?: Record<string, PreparedAsset>;
|
|
31
|
+
/** The state to draw: a preview sets it; an app leaves it to the person. */
|
|
32
|
+
state?: PaywallState;
|
|
33
|
+
/** Entrances as components appear (true); never when the system asks for less motion. */
|
|
34
|
+
animate?: boolean;
|
|
35
|
+
/** Draws as if the system asked for less motion (a preview's choice); the system's own otherwise. */
|
|
36
|
+
reduceMotion?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/** What the person has done to the paywall, and its clock. */
|
|
39
|
+
export interface PaywallState {
|
|
40
|
+
/** The package the person selected. */
|
|
41
|
+
selected?: string;
|
|
42
|
+
/** Each tabs component's tab, and each switch's side, by the component's path. */
|
|
43
|
+
tabs?: Record<string, string>;
|
|
44
|
+
switches?: Record<string, boolean>;
|
|
45
|
+
/** The sheet open, by its id. */
|
|
46
|
+
sheet?: string | null;
|
|
47
|
+
/** When the paywall opened (ms since the epoch): a countdown from its opening counts from here. */
|
|
48
|
+
openedAt?: number;
|
|
49
|
+
/** A moment to draw, held still (ms since the epoch); the clock runs when absent. */
|
|
50
|
+
now?: number;
|
|
51
|
+
}
|
|
52
|
+
export interface PaywallHandlers {
|
|
53
|
+
/** The purchase button, for its package (the one selected, unless it names one) and the offer it is bought with; the button waits while a promise it returns runs. */
|
|
54
|
+
onPurchase(pkg: PaywallPackage): void | Promise<void>;
|
|
55
|
+
/** A restore button; without this one is not drawn (the web restores nothing: Stripe's purchases are the account's). */
|
|
56
|
+
onRestore?(): void | Promise<void>;
|
|
57
|
+
/** A close button; without this one is not drawn (a close inside a sheet closes the sheet). */
|
|
58
|
+
onClose?(): void;
|
|
59
|
+
/** A link the person opened; without this the browser opens it in a new tab. */
|
|
60
|
+
onLink?(url: string): void;
|
|
61
|
+
/** Told when the person picks another package. */
|
|
62
|
+
onSelect?(pkg: PaywallPackage): void;
|
|
63
|
+
/** The paywall's own words, which the definition does not hold: the app's, in its language. */
|
|
64
|
+
labels?: {
|
|
65
|
+
packages?: string;
|
|
66
|
+
close?: string;
|
|
67
|
+
restore?: string;
|
|
68
|
+
};
|
|
69
|
+
/** An offer code button: the web has none to redeem, so without this one is not drawn. */
|
|
70
|
+
onOfferCode?(): void | Promise<void>;
|
|
71
|
+
/** Told whenever the state changes: a preview keeps its controls with it. */
|
|
72
|
+
onState?(state: PaywallState): void;
|
|
73
|
+
/** A designer's canvas: a click picks the component under it (its definition path) instead of acting. */
|
|
74
|
+
editor?: {
|
|
75
|
+
onPick(path: string): void;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export interface PaywallView {
|
|
79
|
+
/** The package selected now. */
|
|
80
|
+
readonly selected: PaywallPackage | null;
|
|
81
|
+
/** Selects a package (`<product>.<plan>`) as the person would. */
|
|
82
|
+
select(key: string): void;
|
|
83
|
+
/** Removes it from the page. */
|
|
84
|
+
destroy(): void;
|
|
85
|
+
/** Draws it again from what changed: a new definition, the other appearance, another language, new prices or assets, a state to show. */
|
|
86
|
+
update(input: Partial<PaywallInput>): void;
|
|
87
|
+
/** The state drawn now. */
|
|
88
|
+
readonly state: PaywallState;
|
|
89
|
+
/** Marks a component (by path) as a designer's canvas does; null clears it. */
|
|
90
|
+
highlight(path: string | null): void;
|
|
91
|
+
/** Plays every entrance again. */
|
|
92
|
+
replay(): void;
|
|
93
|
+
}
|
|
94
|
+
/** What a message is drawn from. */
|
|
95
|
+
export interface MessageInput {
|
|
96
|
+
definition: MessageDefinition;
|
|
97
|
+
/** The reader's language (`tr-TR`). */
|
|
98
|
+
locale: string;
|
|
99
|
+
appearance: Appearance;
|
|
100
|
+
/** Where it is drawn: the web, unless a preview draws another platform's. */
|
|
101
|
+
platform?: Platform;
|
|
102
|
+
/** The values its sender gave, by name (`{{first_name}}`, `{{order}}` …): a text or an address naming one without a value is not drawn. */
|
|
103
|
+
variables?: Readonly<Record<string, string>>;
|
|
104
|
+
/** The definition's assets ready to draw, by id (prepareAssets): one missing is drawn without. */
|
|
105
|
+
assets?: Record<string, PreparedAsset>;
|
|
106
|
+
/** The state to draw: a preview sets it; an app leaves it to the person. */
|
|
107
|
+
state?: MessageState;
|
|
108
|
+
/** Entrances as components appear (true); never when the system asks for less motion. */
|
|
109
|
+
animate?: boolean;
|
|
110
|
+
/** Draws as if the system asked for less motion (a preview's choice); the system's own otherwise. */
|
|
111
|
+
reduceMotion?: boolean;
|
|
112
|
+
}
|
|
113
|
+
/** What the person has done to the message — a tab, a switch's side, a sheet open — and its clock. */
|
|
114
|
+
export type MessageState = Omit<PaywallState, 'selected'>;
|
|
115
|
+
/** A button's action as the person took it, with where the button is: what a campaign counts as a click. */
|
|
116
|
+
export interface MessageActionTaken {
|
|
117
|
+
type: 'close' | 'open_url' | 'deep_link' | 'request_push' | 'show_paywall' | 'custom' | 'sheet' | 'offer';
|
|
118
|
+
url?: string;
|
|
119
|
+
link?: string;
|
|
120
|
+
placement?: string;
|
|
121
|
+
name?: string;
|
|
122
|
+
value?: string;
|
|
123
|
+
sheet?: string;
|
|
124
|
+
offer?: string;
|
|
125
|
+
/** Whether the message closes as it is taken. */
|
|
126
|
+
dismiss: boolean;
|
|
127
|
+
/** The button's path in the definition (`root.children[2]`), and its id when it has one. */
|
|
128
|
+
path: string;
|
|
129
|
+
id?: string;
|
|
130
|
+
}
|
|
131
|
+
export interface MessageHandlers {
|
|
132
|
+
/** The message closes: its close button, or an action that closes it; without this a close button is not drawn (one inside a sheet closes the sheet). */
|
|
133
|
+
onClose?(): void;
|
|
134
|
+
/** Told of every action the person takes, before it is taken. */
|
|
135
|
+
onAction?(action: MessageActionTaken): void;
|
|
136
|
+
/** An https address (open_url); without this the browser opens it in a new tab. */
|
|
137
|
+
onLink?(url: string): void;
|
|
138
|
+
/** A link of the app's (deep_link); without this the page goes to it. */
|
|
139
|
+
onDeepLink?(link: string): void;
|
|
140
|
+
/** The system's push prompt, asked after the message's own ask; without this its button is not drawn. The button waits while a promise it returns runs. */
|
|
141
|
+
onRequestPush?(): void | Promise<void>;
|
|
142
|
+
/** The paywall of a placement; without this its button is not drawn. */
|
|
143
|
+
onShowPaywall?(placement: string): void | Promise<void>;
|
|
144
|
+
/** One of the catalog's offers, by key: bought with, or its grant claimed. Without this its button is not drawn; the button waits while a promise it returns runs. */
|
|
145
|
+
onOffer?(offer: string): void | Promise<void>;
|
|
146
|
+
/** The app's own code, by name; without this its button is not drawn. */
|
|
147
|
+
onCustom?(name: string, value?: string): void;
|
|
148
|
+
/** The message's own words, which the definition does not hold: the app's, in its language. */
|
|
149
|
+
labels?: {
|
|
150
|
+
close?: string;
|
|
151
|
+
};
|
|
152
|
+
/** Told whenever the state changes: a preview keeps its controls with it. */
|
|
153
|
+
onState?(state: MessageState): void;
|
|
154
|
+
/** A designer's canvas: a click picks the component under it (its definition path) instead of acting. */
|
|
155
|
+
editor?: {
|
|
156
|
+
onPick(path: string): void;
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
export interface MessageView {
|
|
160
|
+
/** Removes it from the page. */
|
|
161
|
+
destroy(): void;
|
|
162
|
+
/** Draws it again from what changed: a new definition, the other appearance, another language, new values or assets, a state to show. */
|
|
163
|
+
update(input: Partial<MessageInput>): void;
|
|
164
|
+
/** The state drawn now. */
|
|
165
|
+
readonly state: MessageState;
|
|
166
|
+
/** Marks a component (by path) as a designer's canvas does; null clears it. */
|
|
167
|
+
highlight(path: string | null): void;
|
|
168
|
+
/** Plays every entrance again. */
|
|
169
|
+
replay(): void;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* A link the app opens: an https address, or one of an app's own scheme — never one the browser would run or read
|
|
173
|
+
* (javascript:, data:, file: …). The server's check (kernel/screen, deepLink) holds a definition to it; a renderer
|
|
174
|
+
* given a definition from anywhere else holds itself to it too.
|
|
175
|
+
*/
|
|
176
|
+
export declare const appLink: (s: unknown) => s is string;
|
|
177
|
+
/** Draws a paywall into a container (its content is replaced). */
|
|
178
|
+
export declare function renderPaywall(container: HTMLElement, input: PaywallInput, handlers: PaywallHandlers): PaywallView;
|
|
179
|
+
/**
|
|
180
|
+
* Draws a message into a container (its content is replaced): its content
|
|
181
|
+
* only — what shows it over the app, at an edge or in a list is the
|
|
182
|
+
* container's (presentMessage, an inbox's card).
|
|
183
|
+
*/
|
|
184
|
+
export declare function renderMessage(container: HTMLElement, input: MessageInput, handlers: MessageHandlers): MessageView;
|
|
185
|
+
/** The paywall's styles in its shadow root: a constructed sheet where the browser has them, a style element elsewhere. */
|
|
186
|
+
export declare function adoptStyle(doc: Document, shadow: ShadowRoot, css: string): void;
|